quarta-feira, 19 de dezembro de 2012

Serviço para pegar o nome do município a partir do código IBGE

http://aplicacoes.mds.gov.br/sagirmps/kadu/rest_nome_mun.php

Código IBGE das UFs

"12" => "AC",
"27" => "AL",
"16" => "AP",
"13" => "AM",
"29" => "BA",
"23" => "CE",
"53" => "DF",
"32" => "ES",
"52" => "GO",
"21" => "MA",
"51" => "MT",
"50" => "MS",
"31" => "MG",
"15" => "PA",
"25" => "PB",
"41" => "PR",
"26" => "PE",
"22" => "PI",
"33" => "RJ",
"24" => "RN",
"43" => "RS",
"11" => "RO",
"14" => "RR",
"42" => "SC",
"35" => "SP",
"28" => "SE",
"17" => "TO"


Ou: http://aplicacoes.mds.gov.br/sagirmps/kadu/print_ufs.php?inverte=t
http://aplicacoes.mds.gov.br/sagirmps/kadu/print_ufs.php
Atualizando pra aparecer o nome das UFS:
http://aplicacoes.mds.gov.br/sagirmps/kadu/print_ufs.php?inverte=t&tudo=t

quinta-feira, 22 de novembro de 2012

json_encode transforma string em "null"

Tinha um array $d em PHP assim:
Array ( [0] => xxx27343xxx [1] => MARIA XXX XXXX SILVA [2] => 1 [3] => xxxx2905xxx [4] => 2010-10-20 11:20:09.000000 [5] => 26123837869 [6] => José XXXX Rodrigues )

Quando fazia o json_encode desse array, em vez da string no [6], era apresentado "null". Isso porque "This function only works with UTF-8 encoded data". Aparentemente esses dados estavam em uma codificação diferente de UTF-8, daí o "é" de "José" causa esse erro.
A solução foi simples:

array_walk($d, 'u8');
function u8(&$v, $k)
{
    $v = utf8_encode($v);
}


E aí sim, pude fazer o json_encode sem problemas!

segunda-feira, 12 de novembro de 2012

Programa PHP se comportando como navegador web

Precisava puxar dados de um site, mas era preciso passar pela seleção de diversos parâmetros que são salvos na sessão até que o usuário veja o resultado.
O que fiz foi um fopen, que no exemplo abaixo é feito através de um proxy, peguei o cabeçalho da resposta com o stream_get_meta_data e dentro wrapper_data e busquei pelo comando 'Set-Cookie'. Peguei a string com o Set-Cookie do jeito que veio e coloquei no header das requisições seguintes.

$uf = $_REQUEST['u'];
$mun = $_REQUEST['m'];
if(!$mun || !$uf)
{
    die("m (nome municipio) ou u (sigla UF) nao foi passado.");
}

$authProxy = base64_encode("<proxy_user>:
<proxy_passwd>");
// Création des options de la requête
$opts = array(
   'http' => array (
       'method'=>'GET',
       'proxy'=>'tcp://
<proxy_addr>:<proxy_port>',
       'request_fulluri' => true,
       'header'=>"Proxy-Authorization: Basic $authProxy"
   )
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);

$u = "http://www.obid.senad.gov.br/portais/OBID/conteudo/web/instituicao/index.php?campo_atuacao%5B%5D=st_prevencao&btn_proximo=Proxima+%3E%3E";
$h = fopen($u, 'r', false, $ctx);

$m = stream_get_meta_data($h);

foreach($m['wrapper_data'] as $wd)
{
    if(strpos($wd, 'Set-Cookie') !== false)
    {
        $ck = str_replace('Set-Cookie', 'Cookie', $wd);
    }
}

$opts = array(
   'http' => array (
    'method'=>'GET',
    'proxy'=>'tcp://
<proxy_addr>:<proxy_port>',
    'request_fulluri' => true,
    'header'=>"Proxy-Authorization: Basic $authProxy\r\n" .
        $ck . "\r\n"
   )
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);
$u = "http://www.obid.senad.gov.br/portais/OBID/conteudo/web/instituicao/index.php?ds_estado=" . $uf;
$h = fopen($u, 'r', false, $ctx);

$m = stream_get_meta_data($h);

foreach($m['wrapper_data'] as $wd)
{
    if(strpos($wd, 'Set-Cookie') !== false)
    {
        $ck = str_replace('Set-Cookie', 'Cookie', $wd);
    }
}

$opts = array(
   'http' => array (
    'method'=>'GET',
    'proxy'=>'tcp://
<proxy_addr>:<proxy_port>',
    'request_fulluri' => true,
    'header'=>"Proxy-Authorization: Basic $authProxy\r\n" .
        $ck . "\r\n"
   )
);
// Création du contexte de transaction
$ctx = stream_context_create($opts);

$u = "http://www.obid.senad.gov.br/portais/OBID/conteudo/web/instituicao/index.php?ds_cidade=" . $mun;
$r = file_get_contents($u, false, $ctx);


$r = substr($r, strpos($r, '<ul class="imp">'), strrpos($r, '</ul>'));

print_r($r);

quarta-feira, 8 de agosto de 2012

Verificando se o usuário está autenticado em outro servidor

Tenho um script PHP que está rodando no servidor X. Esse script varia seu comportamento dependendo de o usuário estar autenticado ou não. Porém, o servidor de autenticação é um servidor Y. Como saber em X se o usuário está autenticado em Y? Sem enrolação: o script em questão precisa fazer um session_start() e tem que ter a seguinte linha:
<script src="http://servidorX/verifica_login.php?i=<?= session_id(); ?>" type="text/javascript">

O script verifica_login.php só precisa do seguinte:

$url = "http://servidorY/ajusta_sessao_ok.php?i=" . $_REQUEST['i'];
if(<aqui vem a regra que verifica se o usuário está autenticado em Y>)
{
    $content = file_get_contents($url);
}
else
{
    $url .= "&d=s";
    $content = file_get_contents($url);
}

Já o script ajusta_sessao_ok.php precisa estar no servidor Y:

$id = session_id(trim($_REQUEST['i']));
session_start();
if($_REQUEST['d'] == 's')
{
    unset($_SESSION['autenticacao_ok']);
}
else
{
    $_SESSION['autenticacao_ok'] = true;
}

Daí o script que tem o comportamento variando de acordo com o login do usuário precisa fazer algo do tipo:

session_start();
if($_SESSION['autenticacao_ok'])
{
    // coisas a fazer com o usuário autenticado
}
else
{
    // coisas a fazer com o usuário não autenticado
}

sexta-feira, 18 de maio de 2012

to_ascii funcionando no PostgreSQL

Como certa vez disse o Fabrício Lakus Brito, "lower(to_ascii()) é o que há". Infelizmente essa função não funciona mais para bancos de dados com codificação UTF-8 na versão 8.3. Encontrei no blog Florian Helmberger’s blog a descrição da situação que enfrentamos:
In the process of fixing our code for an upcoming upgrade of one database version for one of our $-projects I encountered a strange behaviour. Initiual situation:
  • we're moving from PostgreSQL 8.1.3 to the 8.3.5
  • we're moving from database encoding LATIN1 to UTF8
  • in our code we're using the TO_ASCII function a few times.
And this combination produces some headaches.
A função to_ascii deixou de funcionar. A solução apresentada nesse blog (que já foi pega de uma outra pessoa) foi:

CREATE FUNCTION to_ascii(bytea, name) RETURNS text STRICT AS 'to_ascii_encname' LANGUAGE internal;

Daí eu uso a função assim:

SELECT to_ascii(convert_to('Übermeier', 'latin1'), 'latin1');

segunda-feira, 7 de maio de 2012

Múltiplas requisições AJAX


Precisava fazer várias requisições ajax a vários servidores. Não queria me preocupar com a ordem das requisições, mas pra possibilitar que todas fossem feitas ao mesmo tempo, precisava criar um objeto XmlHttp para cada uma delas (veja http://www.ibm.com/developerworks/web/library/wa-ajaxintro3/).

Uma solução que estou testando usa closures (veja http://jibbering.com/faq/notes/closures/), que é diferente do Closure Tools (https://developers.google.com/closure/compiler/). Ainda estou aprendendo a mexer com isso, e o resultado foi (atualização 7/2/2013: veja este post: Usando o ajaxStufff):


E o arquivo ajaxStufff.js:

function assoc(xmlHttp, postQueryString, onreadystatechange, action)
{
    return (function() {
        xmlHttp.onreadystatechange=onreadystatechange;
        xmlHttp.open("POST", action, true);
        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlHttp.setRequestHeader("Content-length", postQueryString.length);
        xmlHttp.setRequestHeader("Connection", "close");
        xmlHttp.send(postQueryString);
    });
}

function obterXHR() {
    try
    {
        // Firefox, Opera 8.0+, Safari
        xmlHttp=new XMLHttpRequest();
    }
    catch(e)
    {
        // Internet Explorer
        try
        {
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e)
        {
            try
            {
                xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e)
            {
                alert("Seu navegador não suporta AJAX!");
                return false;
            }
        }
    }
    return xmlHttp;
}