Search neighborhood from street

0

Looking for a little bit I found this method of consulting the ZIP code from neighborhood and city or all the data from the zip code. But this query is only working when I put the information directly in the code in quotation marks. I am not able to use a variable (which I enter the data passed by POST) within $buscarcep->busca('[Aqui dentro!]') .

The problem is the one below in // View routine

This is the code:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento</title>
</head>

<body>



<?php
$rua01 = 'Rua diadema';
$cidade01 = 'Foz do Iguaçu';

$endereco01 = $rua01.' '.$cidade01;

class BuscaCEP
{
    protected function formata($response)
    {
        $dom = new DOMDocument();
        @$dom->loadHTML($response);
        $xpath = new DOMXPath($dom);
        $values = $xpath->query('//*[@class="respostadestaque"]');
        $result = [];

        // Se não encontrar CEP, retorna false
        if (!$values->length) {
            return false;
        }

        // Obtém informações desejadas, tratando-as quando necessário
        foreach ($values as $value) {
            $result[] = preg_replace(
                '~[\s]{2,}~',
                '',
                trim($value->childNodes->item(0)->nodeValue)
            );
        }

        list($logradouro, $bairro, $localidade, $cep) = $result;
        list($localidade, $uf) = explode('/', $localidade);

        return compact('logradouro', 'bairro', 'localidade', 'uf', 'cep');
    }

    public function busca($cep)
    {
        $response = file_get_contents(
            'http://m.correios.com.br/movel/buscaCepConfirma.do',
            false,
            stream_context_create([
                'http' => [
                    'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
                    'method' => 'POST',
                    'content' => http_build_query([
                        'cepEntrada' => $cep,
                        'metodo' => 'buscarCep',
                    ]),
                ],
            ])
        );

        return $this->formata($response);
    }
}

// Rotina de Exibir
$buscarcep = new BuscaCEP();
$dados = $buscarcep->busca($endereco01);
print_r($dados['bairro']);

?>

</body>
</html>

I've already put

$dados = $buscarcep->busca($enderecoP);
$dados = $buscarcep->busca("$enderecoP");

And it just did not show up. No error, simply nothing was printed.

Updating with more information, because they have generated different forms of interpretation. La at the end of the code when I put:

// Rotina de Exibir
$buscarcep = new BuscaCEP();
$dados = $buscarcep->busca($endereco01);
print_r($dados['bairro']);

Within the $ endereco01 variable I have $ rua01. ' '. $ city01 , that if I gave an echo in it, it would be shown Street diadema Foz do Iguaçu . But the way it does not recognize! Now if I take $ endereco01 and just put 'Street address Foz do Iguaçu' like this:

// Rotina de Exibir
$buscarcep = new BuscaCEP();
$dados = $buscarcep->busca('Rua diadema Foz do Iguaçu');
print_r($dados['bairro']);

It fully recognizes and monitors the information for this address.

    
asked by anonymous 01.06.2017 / 01:39

1 answer

4

Here it worked perfectly the way you did, did not change any line the problem should be elsewhere, has no relation with entering or not in $buscarcep->busca(...)

The problem must be either the data coming from POST or the response that you did not handle with $xpath->query('//*[@class="respostadestaque"]'); , if the mail page does not find the address then it should be sending an error message , which you have not captured, PHP does not suggest that an HTML page is reporting an error, unless you program it to do this,

First step

Most important of all, always check the input values:

if (empty($_POST['rua'])) {
   die('Você não informou a rua');
} else if (empty($_POST['cidade'])) {
   die('Você não informou a cidade');
}

$ruaP = $_POST['rua'];
$cidadeP = $_POST['cidade'];
$enderecoP = $ruaP.' '.$cidadeP;
  

Note: As% with_parents are not required to concatenate, they are required to isolate, type when concatenating something that requires different "treatments", or concatenating "calculations" with "string" or doing "calculations in order "

Ready this should help avoid missing information

Second step

The $enderecoP = $ruaP.' '.$cidadeP; is not for printing strings (although it works) is for array, print_r also does not recognize boolean values, your script must be returning print_r (false and true are Booleans) because of this: / p>

// Se não encontrar CEP, retorna false
if (!$values->length) {
    return false;
}

Then change to false , as var_Dump "debug" your variables by saying the type and value:

$dados = $buscarcep->busca($enderecoP);
var_dump($dados);

Third step

Check if there was an error in the post page response, as I said PHP is not a fortune teller, you should make the behavior as human and program PHP to do this, for example I opened the link and typed nonsense random words and got the error page, the post page in the HTML view-source returned this: / p>

<div class="erro">
            Dados nao encontrados         <br>
        </div>

So just adjust to this:

$checkError = $xpath->query('//*[@class="erro"]');

if ($checkError->length) {
    return trim($checkError->item(0)->nodeValue);
}

$values = $xpath->query('//*[@class="respostadestaque"]');
$result = [];

// Se não encontrar CEP, retorna false
if (!$values->length) {
    throw new \Exception('CEP não encontrado');
}

You can also convert to a var_dump , something like:

$checkError = $xpath->query('//*[@class="erro"]');

if ($checkError->length) {
    throw new \Exception(trim($checkError->item(0)->nodeValue));
}

Extra stage

An extra detail of Xpath Exception does not work well for classes (attribute //*[@class="erro"] ), for example it will work with:

But it will not work with:

<div class="class1 class2 respostadestaque class4" ...

So the most appropriate Xpath would be this:

//*[contains(concat(" ", normalize-space(@class), " "), " ' . $classname . ' ")]

Extra stage 2 decoding

Just as I explained in this answer documents can be saved as utf- 8, in this case it is likely that the incoming data coming from strings or POST / GET end up being utf-8, in the case where Anderson noticed, the page does not support "accents" but in the case it should only be accents in "unicode ", if you are sure that your script is in utf-8 then you should use class="..." :

 $dados = $buscarcep->busca(utf8_decode($enderecoP));

If your PHP scripts are using ANSI and iso-8859-1 then you do not need to:

 $dados = $buscarcep->busca($enderecoP);

Final result

It should look more or less like this

<?php

if (empty($_POST['rua'])) {
   die('Você não informou a rua');
} else if (empty($_POST['cidade'])) {
   die('Você não informou a cidade');
}

$ruaP = $_POST['rua'];
$cidadeP = $_POST['cidade'];
$enderecoP = $ruaP . ' ' . $cidadeP;

class BuscaCEP
{
    private static function classSelector($classname) {
        return '//*[contains(concat(" ", normalize-space(@class), " "), " ' . $classname . ' ")]';
    }

    protected function formata($response)
    {
        $dom = new DOMDocument();
        @$dom->loadHTML($response);
        $xpath = new DOMXPath($dom);

        $checkError = $xpath->query(self::classSelector('erro'));

        if ($checkError->length) {
            throw new \Exception(trim($checkError->item(0)->nodeValue));
        }

        $values = $xpath->query(self::classSelector('respostadestaque'));
        $result = [];

        // Se não encontrar CEP, retorna false
        if (!$values->length) {
            throw new \Exception('CEP não encotrado');
        }

        // Obtém informações desejadas, tratando-as quando necessário
        foreach ($values as $value) {
            $result[] = preg_replace(
                '~[\s]{2,}~',
                '',
                trim($value->childNodes->item(0)->nodeValue)
            );
        }

        list($logradouro, $bairro, $localidade, $cep) = $result;
        list($localidade, $uf) = explode('/', $localidade);

        return compact('logradouro', 'bairro', 'localidade', 'uf', 'cep');
    }

    public function busca($cep)
    {
        $response = file_get_contents(
            'http://m.correios.com.br/movel/buscaCepConfirma.do',
            false,
            stream_context_create([
                'http' => [
                    'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
                    'method' => 'POST',
                    'content' => http_build_query([
                        'cepEntrada' => $cep,
                        'metodo' => 'buscarCep',
                    ]),
                ],
            ])
        );

        return $this->formata($response);
    }
}

try {
    $buscarcep = new BuscaCEP();
    $dados = $buscarcep->busca(utf8_encode($enderecoP));
    echo $dados['bairro'];
} catch (\Exception $e) {
    var_dump('Erro:', $e->getMessage()); //Exibe erro
}

If your scripts are saved in ANSI (probably iso-8859-1 / windows-1252):

try {
    $buscarcep = new BuscaCEP();
    $dados = $buscarcep->busca($enderecoP);
    echo $dados['bairro'];
} catch (\Exception $e) {
    var_dump('Erro:', $e->getMessage()); //Exibe erro
}
    
01.06.2017 / 02:45