Validação de Número de Contribuinte Português em PHP

Várias vezes temos necessidade de validar o Número de Identificação Fiscal (NIF), no caso dos particulares, ou Número de Identificação de Pessoa Colectiva (NIPC), no caso das empresas, nas soluções que desenvolvemos para os nossos clientes, pelo que utilizamos uma função PHP para essa validação no lado do servidor.

As regras para a validação do NIF são:

  • Tem de ter 9 dígitos;
  • O primeiro dígito tem de ser 1, 2, 5, 6, 8 ou 9; (Esta é a informação que circula na maior parte dos fóruns da internet, mas a realidade é que o 3 está reservado para uso de particulares assim que os começados por 2 se esgotarem e o 4 e 7 são utilizados em casos especiais, pelo que, por omissão, a nossa função ignora esta validação)
  • O dígito de controlo (último digíto do NIF) é obtido da seguinte forma:
    • 9*d1 + 8*d2 + 7*d3 + 6*d4 + 5*d5 + 4*d6 + 3*d7 + 2*d8 + 1*d9  (em que d1 a d9 são os 9 dígitos do NIF);
    • Esta soma tem de ser múltiplo de 11 (quando divídida por 11 dar 0);
    • Subtraír o resto da divisão da soma por 11 a 11;
    • Se o resultado for 10, é assumído o algarismo 0;

Partilhamos aqui a função PHP, que costumamos utilizar, para validação do NIF/NIPC Português, através do cálculo do check digit do mesmo:

function validaNIF($nif, $ignoreFirst=true) {
	//Limpamos eventuais espaços a mais
	$nif=trim($nif);
	//Verificamos se é numérico e tem comprimento 9
	if (!is_numeric($nif) || strlen($nif)!=9) {
		return false;
	} else {
		$nifSplit=str_split($nif);
		//O primeiro digíto tem de ser 1, 2, 5, 6, 8 ou 9
		//Ou não, se optarmos por ignorar esta "regra"
		if (
			in_array($nifSplit[0], array(1, 2, 5, 6, 8, 9))
			||
			$ignoreFirst
		) {
			//Calculamos o dígito de controlo
			$checkDigit=0;
			for($i=0; $i<8; $i++) {
				$checkDigit+=$nifSplit[$i]*(10-$i-1);
			}
			$checkDigit=11-($checkDigit % 11);
			//Se der 10 então o dígito de controlo tem de ser 0
			if($checkDigit>=10) $checkDigit=0;
			//Comparamos com o último dígito
			if ($checkDigit==$nifSplit[8]) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
}

A Webdados está disponível para lhe prestar qualquer serviço na área do desenvolvimento para a internet.

4 comentários a Validação de Número de Contribuinte Português em PHP

  1. Keoni 2015-03-24 às 12:18 #

    Atenção: os NIF também começam por 7, nomeadamente NIFs de Heranças Indivisas (entre outras).
    A alteração é simples já que passa por adicionar o dígito 7 à lista dos válidos.
    Abraço!

  2. Jorge Neto 2015-05-15 às 21:54 #

    Para os que quiserem podem ter esta validação na base de dados. Aqui fica um exemplo em MySql

    CREATE FUNCTION `validafis`( ff char(13)) RETURNS char(1) CHARSET utf8
    DETERMINISTIC
    BEGIN
    — valida o numero fiscal nacional
    — Jorge Neto 2013
    DECLARE n9 char(1) DEFAULT substring(ff,9,1);
    DECLARE chk int(8);
    if length(ff)9 then return 0; end if;
    if substring(ff,1,1) not in (1,2,5,6,7,8,9) then return 0; end if;
    set chk = Mod((substring(ff,1,1)*9 + substring(ff,2,1)*8 + substring(ff,3,1)*7 + substring(ff,4,1)*6 + substring(ff,5,1)*5 + substring(ff,6,1)*4 + substring(ff,7,1)*3 + substring(ff,8,1)*2),11);
    set chk = if(chk > 1,11-chk,0);
    RETURN (select if(chk=n9,1,0));
    END

  3. Joan Az Po 2016-11-24 às 11:42 #

    Els deixo aqui una funció per a la validació per a Javascript i per a generar el dígit de control a partir dels 8 primers caràcters.

    var DNIpt = function(dni){
    dniNaN = isNaN(dni);
    if(dniNaN){
    return false;
    }else{
    dnisplit = dni.toString();
    dnisplit = dnisplit.split(”);

    checkDigit = 0;
    for(i =0;i=10){
    checkDigit = 0;
    }
    if(checkDigit == dnisplit[8]){
    return true;
    }else{
    return false;
    }
    }
    }
    var ptt = function(dni){
    dnisplit = dni.toString();
    dnisplit = dnisplit.split(”);
    checkDigit = 0;

    for(i =0;i<8; i++){
    checkDigit+=dnisplit[i]*(10-i-1);
    }
    checkDigit = 11-(checkDigit%11);
    return checkDigit;
    }

  4. Webdados 2016-12-19 às 10:52 #

    Gracias 🙂

Deixe uma resposta

*