PHP - Obtendo todos os CEPs do Brasil
Olá Gente!
Certamente você já passou por este desafio.
Sei que existe várias APIs que fornecem o Endereço de um CEP determinado, mas, toda API pode ficar offline, e em um E-commerce o Endereço é uma informação muito importante.
Então, ter uma base de CEPs local, que possa possa consultar gera muitos benéficos:
- Sempre estar online (Enquanto sua aplicação estiver online, rs)
- Menor tempo de resposta
- Controle de atualização (Afinal, você ira precisar atualizar esta base regularmente)
Se você já buscou por uma base de CEPs, sabe que não é barato, todos que conseguem cobram:
Um absurdo total! Cobrar para fornecer os endereços das ruas!
Mas, aqui meu objetivo é diferente, é promover o conhecimento de como obter o que você precisa sem gastar valor abusivos.
Para esta missão, iremos utilizar a API oficial dos correios, assim, iremos ter dados bem atualizados.
Antes de tudo, você precisa ter um acesso EMPRESA ao site dos correios, isto ira permitir acessar a API de CEPs.
Gerando Credenciais
Acesse o painel de desenvolvedor dos correios em:
Clique em "Entrar" e preencha os dados de sua conta nos correios:
Após entrar em sua conta, clique em "Gestão de Acesso a API's":
No campo "Usuário do Portal Meu Correios" será exibido o Usuário de acesso a API:
Confirme sua senha e clique em "Regenerar Código":
Caso exiba uma janela "Você já possui um código!" clique em "Sim":
Será exibido seu Token, COPIE este Token:
Além destes dados, é necessário o número do seu "Cartão de Postagem":
Agora já temos os dados de acesso a API!
Gerando Access Token
Os correios possuem uma geração de Access Token antes de conseguir utilizar os métodos da API.
Com isto, é necessário enviar um POST para:
https://api.correios.com.br/token/v1/autentica/cartaopostagem
Onde iremos enviar, no Header, uma "Autenticação Basic":
{
"Authorization: Basic [Usuario]:[Senha]"
}
E nos dados, iremos enviar um Json, com o cartão de postagem:
{
"numero": "[CartaoDePostagem]"
}
Em caso de sucesso, será retornado um "HttpCode 200", com um Json, onde precisamos extrair apenas o campo "token":
{
"token": "XXXXXXXXXXXXXXXXXXXXXXXXX"
}
Este Token, iremos enviar em toda requisição, no Header, através da "Autenticação Bearer":
{
"Authorization: Bearer [AccessToken]"
}
Obtendo Endereços dos CEPs
Agora vem a parte Legal!
Os correios possuem uma API que permite buscar blocos de 1000 CEPs! Você não achou que iriamos buscar um a um né?
Para isto, precisamos fazer uma GET para:
https://api.correios.com.br/cep/v2/enderecos
No Header, precisamos enviar o Access Token:
{
"Authorization: Bearer [AccessToken]"
}
E, na QueryString, os parâmetros abaixo:
- size: Quantidade de registros por página - Iremos enviar "1000"
- page: A Página Atual, começando em "0"
- sort: A ordenação - Iremos enviar "cep,asc"
Como retorno, iremos receber um Json semelhante ao Json abaixo:
{
"itens": [
{
"cep": "01001000",
"uf": "SP",
"numeroLocalidade": 96681,
"localidade": "São Paulo",
"logradouro": "Praça da Sé",
"tipoLogradouro": "Praça",
"nomeLogradouro": "da Sé",
"complemento": "- lado ímpar",
"abreviatura": "Pç da Sé",
"bairro": "Sé",
"tipoCEP": 2,
"cepUnidadeOperacional": "01032970",
"lado": "I",
"numeroInicial": 1,
"numeroFinal": 999
}
],
"page": {
"size": 2,
"totalElements": 1311130,
"totalPages": 655565,
"number": 0
}
}
No elemento "itens" iremos ter um array com todos os CEPs retornado.
No elemento "page" temos a paginação:
- totalElements: Quantidade de CEPs que existem
- totalPages: Quantidade de Páginas
Criando um Loop com PHP
Agora já que sabemos o conceito, podemos criar um PHP, que busque de 1000 em 1000, e com os resultados salvamos em uma base de dados!
Para isto, deixei um repositório prontinho:
Base de Dados Pronta
Meu intuito aqui é ensinar como fazer, porem, sei que nem todo mundo tem tempo de ficar buscando todos os CEPs.
Para facilitar, gerei um Dump da base de CEPs, para você baixar e importar em seu sistema:
Depois de importar o SQL para sua base de dados, basta fazermos um simples select para retornar o endereço do CEP:
Select
*
From
ceps
where
CEP_Faixa = '70040'
And
CEP = '70040010'
Porque a coluna CEP_Faixa?
Atualmente, temos perto de 1 milhão e 300 mil CEPs, um select nesta base é demorado.
Para exemplo, vamos buscar um CEP:
Select
*
From
ceps
where
CEP = '70040010'
Vamos analisar esta consulta:
Onde Temos:
- Linhas: 1290116
- Tempo: 0.781 seg
Ou seja, foi necessário ler a tabela toda! O que é custoso para o desempenho.
Agora, vamos refazer esta mesma consulta, utilizando a coluna CEP_Faixa:
Select
*
From
ceps
where
CEP_Faixa = '70040'
And
CEP = '70040010'
Vamos analisar esta consulta:
Onde Temos:
- Linhas: 1
- Tempo: 0 seg
Observe o ganho absurdo de velocidade!
Em um E-commerce, esta diferença é muito significante!
Por hoje é só, meus unicórnios! 🦄✨
Que a magia do arco-íris continue brilhando em suas vidas! Até mais! 🌈🌟"