Consultando CEP direto dos correios com PHP
A idéia é usar o PHP para conectar no site dos Correios enviando o CEP a ser pesquisado, pelo mesmo endereço que os usuários normalmente consultam.
Atenção
Pois é amiguinhos, como eu temia, os correios abandonou a URL mobile, e perdemos acesso para a solução apresentada neste tutorial
Nesse caso busquem alternativas para a consulta. Vou listar algumas opções que conheço, sinta-se livre para postar outras soluções que atualizarei o post.
Essas sugestões são uma forma de escape, mas não ajudaremos vocês com nenhum deles, nesse caso se tiverem problemas ao tentar usar a API, peço que entre em contato com os respectivos sites. Sorry :(
Para efeitos de história, vou deixar abaixo a solução que usávamos
Antes de mais nada, existem soluções melhores que essa, mas eu quis ser diferente e capturar os dados de outra maneira. Já podem me julgar...
Como de costume: Se você manda bem no PHP, clique aqui ir direto ao código completo.
Começando a mineração
Os correios espera dois campos, o CEP e um parametro metodo com valor buscarCep. Deixaremos esses dados prontos para enviar via POST depois.
1
2
3
4
$data = array(
'cepEntrada' => '04476240',
'metodo' => 'buscarCep',
);
Hora de converter o array em uma query para facilitar no envio.
$data = http_build_query($data);
Iniciando o cURL e passando a URL dos correios
$curl = curl_init('http://m.correios.com.br/movel/buscaCepConfirma.do');
Configurar o envio como post e passar a variável com os dados do post
1
2
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
Informando ao cURL que queremos o resultado em uma variável
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
Executando a conexão e guardando o resultado na variável
$html = curl_exec($curl);
Fechando a conexão
curl_close($curl);
Se você mandar imprimir na tela a variável $html vai ver que ele trouxe toda página dos correios com o resultado do frete.
É exatamente o que nós queremos. Agora é hora de eliminar o que não queremos da página. Usaremos a função explode para ir "partindo", os pedaços que queremos.
Se você ver a estrutura do HTML da página dos correios, poderá notar que se explodirmos resposta"> teremos a informação que precisamos.
$html = explode('resposta">', $html);
Elininando o indice zero onde temos apenas o começo do HTML sem informação útil.
unset($html[0]);
Já temos um array com as informações que precisamos, vamos navegar pelos dados pegando só o necessário. Criaremos um array $cep para deixar as informações que recebemos do CEP.
1
2
3
4
$cep = array();
foreach ($html as $key => $row) {
//Trataremos tudo aqui
}
Dentro do laço (foreach) nossa missão é pegar o nome da informação, colocar na variável $label e o valor da informação colocando na variável $value
Pegando a primeira parte antes do ":", teremos nosso rótulo
1
2
$label = explode(':', $row);
$label = current($label);
Se quisermos deixar "bonitinho" e padronizado, poderemos usar a função Slugify
$label = slugify($label);
Pronto, nosso rótulo já está pronto. Podemos seguir para o próximo.
Note que podemos explodir respostadestaque"> e termos o valor da informação
$value = explode('respostadestaque">', $row);
O que importa para nós é o conteudo do indice 1
$value = $value[1];
O primeiro valor antes do span
1
2
$value = explode('</span>', $value);
$value = current($value);
Removendo os espaços antes e depois
$value = trim($value);
Removendo as quebras de linhas, tabs e retornos
$value = preg_replace('/[\n\t\r]/', ' ', $value);
Qualquer espaço duplo
$value = preg_replace('/\s(?=\s)/', '', $value);
Se sua página estiver em UTF-8, inclua a linha abaixo
$value = utf8_encode($value);
Pronto. Agora já temos toda informação que precisamos, do jeito que precisamos. Basta popular o array $cep, usando o $label como indice e $value como valor.
$cep[$label] = $value;.
Missão cumprida.
Agora a idéia é colocar tudo dentro de uma função que receba o $cep e retorne as informações.
1
2
3
4
function CEP($cep) {
//Todo conteúdo passado anteriormente
return $cep;
}
Código completo e já na função ficará algo como abaixo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
function CEP($cep) {
$data = array(
'cepEntrada' => $cep,
'metodo' => 'buscarCep',
);
$data = http_build_query($data);
$curl = curl_init('http://m.correios.com.br/movel/buscaCepConfirma.do');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($curl);
curl_close($curl);
$html = explode('resposta">', $html);
unset($html[0]);
$cep = array();
foreach ($html as $key => $row) {
$label = explode(':', $row);
$label = current($label);
$label = slugify($label);
$value = explode('respostadestaque">', $row);
$value = $value[1];
$value = explode('</span>', $value);
$value = current($value);
$value = trim($value);
$value = preg_replace('/[\n\t\r]/', ' ', $value);
$value = preg_replace('/\s(?=\s)/', '', $value);
$value = utf8_encode($value);
$cep[$label] = $value;
}
return $cep;
}