-
Star
(172)
You must be signed in to star a gist -
Fork
(30)
You must be signed in to fork a gist
-
-
Save rafael-neri/ab3e58803a08cb4def059fce4e3c0e40 to your computer and use it in GitHub Desktop.
<?php | |
function validaCPF($cpf) { | |
// Extrai somente os números | |
$cpf = preg_replace( '/[^0-9]/is', '', $cpf ); | |
// Verifica se foi informado todos os digitos corretamente | |
if (strlen($cpf) != 11) { | |
return false; | |
} | |
// Verifica se foi informada uma sequência de digitos repetidos. Ex: 111.111.111-11 | |
if (preg_match('/(\d)\1{10}/', $cpf)) { | |
return false; | |
} | |
// Faz o calculo para validar o CPF | |
for ($t = 9; $t < 11; $t++) { | |
for ($d = 0, $c = 0; $c < $t; $c++) { | |
$d += $cpf[$c] * (($t + 1) - $c); | |
} | |
$d = ((10 * $d) % 11) % 10; | |
if ($cpf[$c] != $d) { | |
return false; | |
} | |
} | |
return true; | |
} |
Obrigado @WernerLuiz92, @pferreirafabricio e @narcisspicpay
Excelente código Rafael, parabéns!
Muito bom! valeeu
God! A parte dos números repetidos é que eu estava procurando se alguém já tinha feito em preg_match. Apesar de só implementar essa parte, deixarei os louváveis kudos nos comments do script haha. Muito obrigado.
Muito bom e simples!
@queliom eu fiz o teste com o CPF 566.932.570-20 e está funcionando corretamente.
A função foi feita seguindo a documentação contendo a regra de validação de CPF.
@rafael-neri Obrigado man!
Olá, @rafael-neri. Você já testou essa validação com o WP Forms (plugin de formulários para WordPress)?
Sabe dizer se funciona?
Como seria a implementação, nesse caso?
@marcomurta1402 eu não uso wordpress então não sei dizer como seria a implementação.
Mas se esse plugin de formulários permitir adicionar validações em PHP então sim funcionaria.
@rafael-neri eu vou testar e se rolar eu respondo aqui. Valeu!
@marcomurta1402 se conseguiu usar o validador dentro do wordpress, cria um gist e deixa o link aqui.
Será de grande ajuda caso alguém mais precise usar.
@rafael-neri Esbarrei no mesmo problema no wordpress, estou usando o plugin do Cláudio pra validação final de CPF, mas fiz esse código em javascript pra uma validação assim que o campo dispara a ação Blur e usei o código da receita pr validar o CPF:
Incluir código no Footer, não no header.
<script>
const constCPF= document.getElementById('cpf');
const form = document.getElementById('checkout_form');
constCPF.addEventListener("focus", function(event){
event.target.style.background = "white"
}, true);
constCPF.addEventListener("blur", function(event){
var string = document.getElementById('cpf').value;
var strCPF = string.replace('.','').replace('-','').replace('.','') ;
if (TestaCPF(strCPF)!=true){
alert("CPF inválido")
event.target.style.background = "#ff00007a"
}else{
event.target.style.background = "#00b6ff29"
}
}, true);
function TestaCPF(strCPF) {
var Soma;
var Resto;
Soma = 0;
if (strCPF == "00000000000") return false;
for (i=1; i<=9; i++) Soma = Soma + parseInt(strCPF.substring(i-1, i)) * (11 - i);
Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(strCPF.substring(9, 10)) ) return false;
Soma = 0;
for (i = 1; i <= 10; i++) Soma = Soma + parseInt(strCPF.substring(i-1, i)) * (12 - i);
Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(strCPF.substring(10, 11) ) ) return false;
return true;
}
</script>
usei no footer, Ele deixa o campo Azul quando validado, e quando digitar um CPF invalido o campo fica vermelho e um alerta aparece na tela informando o usuário do erro.
Links de fontes dos códigos e lógicas usadas:
Verificação do CPF: https://www.devmedia.com.br/validar-cpf-com-javascript/23916
Outras discução do mesmo problema:https://wordpress.org/support/topic/problemas-com-validacao-do-cpf/
Pluggin do claudio:https://github.com/claudiosanches/woocommerce-extra-checkout-fields-for-brazil
Código de event trigger pra focus e blur:https://www.youtube.com/watch?v=kXq6tO5fqnU
Remoção de caracteres especiais do texto: https://pt.stackoverflow.com/questions/345075/como-receber-o-n%C3%BAmero-de-cpf-e-formatar-para-ficar-sem-os-pontos-e-tra%C3%A7oinput-m
@sr-adulis e demais:
Para a utilização no Front, eu recomendo o uso de uma Lib chamada js-brasil com validações brasileiras.
Segue abaixo um exemplo simples com JQuery.
<input type="text" id="cpf"/>
<script src="https://cdn.jsdelivr.net/npm/js-brasil/js-brasil.js"></script>
<script>
$("#cpf").on("blur", function(){
let cpf_value = $(this).val();
if(jsbrasil.validateBr.cpf(cpf_value)) {
alert("CPF Válido");
} else {
alert("CPF inválido")
}
});
</script>
Para testar o código acima: https://jsfiddle.net/d6ncju1f/
Valew! Código top, usei em meu projeto LARAVEL e funcionou perfeitamente. Parabéns!!!!
eu faço assim
echo $cpf = formatar_cpf_cnpj('039.943.865-35');
function formatar_cpf_cnpj($doc) {
$doc = preg_replace("/[^0-9]/", "", $doc);
$qtd = strlen($doc);
if($qtd >= 11) {
if($qtd === 11 ) {
$docFormatado = substr($doc, 0, 3) . '.' .
substr($doc, 3, 3) . '.' .
substr($doc, 6, 3) . '.' .
substr($doc, 9, 2);
} else {
$docFormatado = substr($doc, 0, 2) . '.' .
substr($doc, 2, 3) . '.' .
substr($doc, 5, 3) . '/' .
substr($doc, 8, 4) . '-' .
substr($doc, -2);
}
return $docFormatado;
} else {
return 'Documento invalido';
}
}
@MauricioSarmento a ideia do script é verificar se o CPF é válido. E não apenas formatar.
Off: Chat GPT anda lendo teu git, pedi uma função em php para validar CPF e ele me mostrou praticamente o mesmo código! Seloko!
Parabéns, man!
Tão boa que o Copilot já mapeou ela 😉, só "esqueceu" de corrigir o que o @jonasbraga comentou.
@indianabytes eu fui verificar e realmente ele mostra essa função no ChatGPT.
@juniormartinxo no caso do Copilot ele aprende com os códigos do Github.
Isso significa que tem muito código que ainda usa o formato antigo, sem as sugestões do @jonasbraga.
@_rafaelneri valeu meu jovem, sucesso e forte abraço!
Ele verifica a existência ou não do cpf?
Isso não é possivel fazer.
Eu costumo validar o cpf (em javascript) assim, valida super bem, até mesmo se existe ou não
/*
* return true|false
*/
ValidaCPF(cpf){
const strCPF = cpf.replaceAll(/\D/g , "");
var Soma = 0;
for (var i=1; i<=9; i++) {
var Soma = Soma + parseInt(strCPF.substring(i - 1, i)) * (11 - i);
}
var Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(strCPF.substring(9, 10)) ) {
return false;
}
Soma = 0;
for (i = 1; i <= 10; i++) {
Soma = Soma + parseInt(strCPF.substring(i - 1, i)) * (12 - i)
}
Resto = (Soma * 10) % 11;
if ((Resto == 10) || (Resto == 11)) Resto = 0;
if (Resto != parseInt(strCPF.substring(10, 11) ) ) {
return false;
}
return true;
}
Eu costumo validar o cpf (em javascript) assim, valida super bem, até mesmo se existe ou não
/* * return true|false */ ValidaCPF(cpf){ const strCPF = cpf.replaceAll(/\D/g , ""); var Soma = 0; for (var i=1; i<=9; i++) { var Soma = Soma + parseInt(strCPF.substring(i - 1, i)) * (11 - i); } var Resto = (Soma * 10) % 11; if ((Resto == 10) || (Resto == 11)) Resto = 0; if (Resto != parseInt(strCPF.substring(9, 10)) ) { return false; } Soma = 0; for (i = 1; i <= 10; i++) { Soma = Soma + parseInt(strCPF.substring(i - 1, i)) * (12 - i) } Resto = (Soma * 10) % 11; if ((Resto == 10) || (Resto == 11)) Resto = 0; if (Resto != parseInt(strCPF.substring(10, 11) ) ) { return false; } return true; }
Seu código não valida se existe um CPF, ele supostamente só valida se a sequência de números é uma sequência válida, isso não significa que o CPF exista de fato. São coisas diferentes. Unica maneira de se validar a existência de um CPF é através do site da Receita Federal.
Show de bola, parabéns!
Ola, por acaso algum de voces ja conseguiram colocar validador no user registration?
Versão para Laravel 11
Executar comando na raiz do projeto
php artisan make:rule ValidaCPF
Classe criada com o comando anterior deverá ficar assim:
<?php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class ValidaCPF implements ValidationRule
{
/**
* Run the validation rule.
*
* @param \Closure(string, ?string=): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
//https://gist.github.com/rafael-neri/ab3e58803a08cb4def059fce4e3c0e40
// rafael-neri/validar_cpf.php
// Extrai somente os números
$cpf = preg_replace( '/[\D]/is', '', $value );
// Verifica se foi informado todos os digitos corretamente
if (strlen($cpf) != 11) {
$fail('O :attribute deve ter exatamente 11 números.');
}
// Verifica se foi informada uma sequência de digitos repetidos. Ex: 111.111.111-11
if (preg_match('/(\d)\1{10}/', $cpf)) {
$fail('O :attribute não deve ser uma sequência de números iguais.');
}
// Faz o calculo para validar o CPF
for ($t = 9; $t < 11; $t++) {
for ($d = 0, $c = 0; $c < $t; $c++) {
$d += $cpf[$c] * (($t + 1) - $c);
}
$d = ((10 * $d) % 11) % 10;
if ($cpf[$c] != $d) {
$fail('O :attribute não é um número válido.');
}
}
}
}
Depois que a regra for definida, você pode anexá-la a um validador, como o exemplo a seguir:
<?php
use App\Rules\ValidaCPF;
$request->validate([
'cpf' => ['required', 'string', new ValidaCPF],
]);
Boa @hiltonbruce
@hiltonbruce se a função der um strlen diferente de 11, ele não vai retornar imediatamente a closure $fail, a função vai tentar verificar as outras regras, se o o usuário colocar uma string menor de 9 ele vai jogar um exception de offset quando o php tentar executar o "for". Aqui está o bug corrigido.
/**
* Run the validation rule.
*
* Extrai somente os números
* Verifica se foi informado todos os digitos corretamente
* Verifica se foi informada uma sequência de digitos repetidos. Ex: 111.111.111-11
* Faz o calculo para validar o CPF
*
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$cpf = apenasNumeros($value);
if (strlen($cpf) !== 11) {
$fail('O :attribute deve ter exatamente 11 números.');
} elseif (preg_match('/(\d)\1{10}/', $cpf)) {
$fail('O :attribute não deve ser uma sequência de números iguais.');
} else {
for ($t = 9; $t < 11; $t++) {
for ($d = 0, $c = 0; $c < $t; $c++) {
$d += $cpf[$c] * (($t + 1) - $c);
}
$d = ((10 * $d) % 11) % 10;
if ($cpf[$c] != $d) {
$fail('O :attribute não é um número válido.');
}
}
}
}
para limpar um pouco mais o código eu coloquei a lógica de regex para limpar os caracteres do cpf em um helper "apenasNumeros", mas a lógica é a mesma ainda.
Obrigado, @rafael-neri !!
Ótima solução! Obrigado por compartilhar e parabéns!