File: /home/onlyfibr/public_html/api/cpf_cnpj/cpf_cnpj.php
<?php
/**
* Exemplo de uso:
* $cpf_cnpj = new valida_cpf_cnpj('71569042000196');
* $formatado = $cpf_cnpj->formata(); // 71.569.042/0001-96
* $valida = $cpf_cnpj->valida(); // True -> Válido
*/
class valida_cpf_cnpj{
/**
* Configura o valor (Construtor)
*
* Remove caracteres inválidos do CPF ou CNPJ
*
* @param string $valor - O CPF ou CNPJ
*/
function __construct ( $valor = null ) {
// Deixa apenas números no valor
$this->valor = preg_replace( '/[^0-9]/', '', $valor );
// Garante que o valor é uma string
$this->valor = (string)$this->valor;
}
/**
* Verifica se é CPF ou CNPJ
*
* Se for CPF tem 11 caracteres, CNPJ tem 14
*
* @access protected
* @return string CPF, CNPJ ou false
*/
protected function verifica_cpf_cnpj () {
// Verifica CPF
if ( strlen( $this->valor ) === 11 ) {
return 'CPF';
}
// Verifica CNPJ
elseif ( strlen( $this->valor ) === 14 ) {
return 'CNPJ';
}
// Não retorna nada
else {
return false;
}
}
/**
* Verifica se todos os números são iguais
* *
* @access protected
* @return bool true para todos iguais, false para números que podem ser válidos
*/
protected function verifica_igualdade() {
// Todos os caracteres em um array
$caracteres = str_split($this->valor );
// Considera que todos os números são iguais
$todos_iguais = true;
// Primeiro caractere
$last_val = $caracteres[0];
// Verifica todos os caracteres para detectar diferença
foreach( $caracteres as $val ) {
// Se o último valor for diferente do anterior, já temos
// um número diferente no CPF ou CNPJ
if ( $last_val != $val ) {
$todos_iguais = false;
}
// Grava o último número checado
$last_val = $val;
}
// Retorna true para todos os números iguais
// ou falso para todos os números diferentes
return $todos_iguais;
}
/**
* Multiplica dígitos vezes posições
*
* @access protected
* @param string $digitos Os digitos desejados
* @param int $posicoes A posição que vai iniciar a regressão
* @param int $soma_digitos A soma das multiplicações entre posições e dígitos
* @return int Os dígitos enviados concatenados com o último dígito
*/
protected function calc_digitos_posicoes( $digitos, $posicoes = 10, $soma_digitos = 0 ) {
// Faz a soma dos dígitos com a posição
// Ex. para 10 posições:
// 0 2 5 4 6 2 8 8 4
// x10 x9 x8 x7 x6 x5 x4 x3 x2
// 0 + 18 + 40 + 28 + 36 + 10 + 32 + 24 + 8 = 196
for ( $i = 0; $i < strlen( $digitos ); $i++ ) {
// Preenche a soma com o dígito vezes a posição
$soma_digitos = $soma_digitos + ( $digitos[$i] * $posicoes );
// Subtrai 1 da posição
$posicoes--;
// Parte específica para CNPJ
// Ex.: 5-4-3-2-9-8-7-6-5-4-3-2
if ( $posicoes < 2 ) {
// Retorno a posição para 9
$posicoes = 9;
}
}
// Captura o resto da divisão entre $soma_digitos dividido por 11
// Ex.: 196 % 11 = 9
$soma_digitos = $soma_digitos % 11;
// Verifica se $soma_digitos é menor que 2
if ( $soma_digitos < 2 ) {
// $soma_digitos agora será zero
$soma_digitos = 0;
} else {
// Se for maior que 2, o resultado é 11 menos $soma_digitos
// Ex.: 11 - 9 = 2
// Nosso dígito procurado é 2
$soma_digitos = 11 - $soma_digitos;
}
// Concatena mais um dígito aos primeiro nove dígitos
// Ex.: 025462884 + 2 = 0254628842
$cpf = $digitos . $soma_digitos;
// Retorna
return $cpf;
}
/**
* Valida CPF
*
* @author Luiz Otávio Miranda <contato@tutsup.com>
* @access protected
* @param string $cpf O CPF com ou sem pontos e traço
* @return bool True para CPF correto - False para CPF incorreto
*/
protected function valida_cpf() {
// Captura os 9 primeiros dígitos do CPF
// Ex.: 02546288423 = 025462884
$digitos = substr($this->valor, 0, 9);
// Faz o cálculo dos 9 primeiros dígitos do CPF para obter o primeiro dígito
$novo_cpf = $this->calc_digitos_posicoes( $digitos );
// Faz o cálculo dos 10 dígitos do CPF para obter o último dígito
$novo_cpf = $this->calc_digitos_posicoes( $novo_cpf, 11 );
// Verifica se todos os números são iguais
if ( $this->verifica_igualdade() ) {
return false;
}
// Verifica se o novo CPF gerado é idêntico ao CPF enviado
if ( $novo_cpf === $this->valor ) {
// CPF válido
return true;
} else {
// CPF inválido
return false;
}
}
/**
* Valida CNPJ
*
* @author Luiz Otávio Miranda <contato@tutsup.com>
* @access protected
* @param string $cnpj
* @return bool true para CNPJ correto
*/
protected function valida_cnpj () {
// O valor original
$cnpj_original = $this->valor;
// Captura os primeiros 12 números do CNPJ
$primeiros_numeros_cnpj = substr( $this->valor, 0, 12 );
// Faz o primeiro cálculo
$primeiro_calculo = $this->calc_digitos_posicoes( $primeiros_numeros_cnpj, 5 );
// O segundo cálculo é a mesma coisa do primeiro, porém, começa na posição 6
$segundo_calculo = $this->calc_digitos_posicoes( $primeiro_calculo, 6 );
// Concatena o segundo dígito ao CNPJ
$cnpj = $segundo_calculo;
// Verifica se todos os números são iguais
if ( $this->verifica_igualdade() ) {
return false;
}
// Verifica se o CNPJ gerado é idêntico ao enviado
if ( $cnpj === $cnpj_original ) {
return true;
}
}
/**
* Valida
*
* Valida o CPF ou CNPJ
*
* @access public
* @return bool True para válido, false para inválido
*/
public function valida () {
// Valida CPF
if ( $this->verifica_cpf_cnpj() === 'CPF' ) {
// Retorna true para cpf válido
return $this->valida_cpf();
}
// Valida CNPJ
elseif ( $this->verifica_cpf_cnpj() === 'CNPJ' ) {
// Retorna true para CNPJ válido
return $this->valida_cnpj();
}
// Não retorna nada
else {
return false;
}
}
/**
* Formata CPF ou CNPJ
*
* @access public
* @return string CPF ou CNPJ formatado
*/
public function formata() {
// O valor formatado
$formatado = false;
// Valida CPF
if ( $this->verifica_cpf_cnpj() === 'CPF' ) {
// Verifica se o CPF é válido
if ( $this->valida_cpf() ) {
// Formata o CPF ###.###.###-##
$formatado = substr( $this->valor, 0, 3 ) . '.';
$formatado .= substr( $this->valor, 3, 3 ) . '.';
$formatado .= substr( $this->valor, 6, 3 ) . '-';
$formatado .= substr( $this->valor, 9, 2 ) . '';
}
}
// Valida CNPJ
elseif ( $this->verifica_cpf_cnpj() === 'CNPJ' ) {
// Verifica se o CPF é válido
if ( $this->valida_cnpj() ) {
// Formata o CNPJ ##.###.###/####-##
$formatado = substr( $this->valor, 0, 2 ) . '.';
$formatado .= substr( $this->valor, 2, 3 ) . '.';
$formatado .= substr( $this->valor, 5, 3 ) . '/';
$formatado .= substr( $this->valor, 8, 4 ) . '-';
$formatado .= substr( $this->valor, 12, 14 ) . '';
}
}
// Retorna o valor
return $formatado;
}
}