function isValidPassword($password) {
$pattern = '/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d].\S{8,36}$/';
return preg_match($pattern, $password) ? true : false;
}
Você é bom em REGEX? Sabe o que é ou para que serve? Já precisou aplicar regras de validação de senhas e não usou REGEX? Então você pode ler este artigo para começar a explorar mais sobre este recurso.
Primeiramente vou deixar claro que o objetivo do artigo não é ensinar REGEX amplamente, ao invés disso vamos aplicar o recurso num problema prático explicando o processo de validação de senhas segundo um cenário de regras, aqui vai…
Regra 1 – A senha deve ter no mínimo 8 e no máximo 36 caracteres.
Regra 2 – A senha deve ser composta de ao menos 1 número, ao menos uma letra maiúscula, e ao menos uma letra minúscula.
Regra 3 – A senha deve ser composta de apenas letras e números e não deve possuir nenhum tipo de caracteres especiais.
No PHP para verificarmos um texto com REGEX podemos usar o recurso preg_match. Como o nome já diz o comando vai verificar o conteúdo do texto segundo uma combinação de máscaras para encontrar a combinação desejada.
Confuso? Então vamos a parte prática, observe primeiramente a máscara postada com esta sintaxe.
'/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d].\S{8,36}$/'
Para entender como a regra funciona temos que desmontá-la e explicar em partes.
Entenda que com REGEX você monta uma máscara aos poucos, assim tente não pensar em aplicar a regra 1 primeiro, depois a regra 2 e no final a regra 3. Geralmente temos que começar aplicar o que é mais fácil, mais simples e ir aumentando a complexidade gradativamente.
'/(?=.*\d)/'
Esta máscara garante que a senha contenha ao menos 1 número, o que é parte da exigência da regra 2.
Pense nesta máscara como sendo uma varredura completa do texto onde ? é cada um dos caracteres da senha podendo ser igual a qualquer coisa (.*) desde que seja numérico (\d).
'/(?=.*\d)(?=.*[a-z])/'
Esta segunda parte garante que a senha contenha ao menos 1 letra minúscula, que também é parte da exigência da regra 2.
Pense que cada máscara entre parênteses é uma varredura individual em que o resultado da varredura deve ser TRUE quando fizer o match desejado.
'/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/'
O terceiro parênteses contém a mesma validação que o segundo, só que como o REGEX é case sensitive por padrão temos que validar com os dois formatos separadamente, letras minúsculas e letras maiúsculas separamente.
'/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d]/'
A próxima máscara adicionada quase garante que todos os caracteres do texto sejam letras e números apenas. Sim, eu disse quase, mas ainda temos que garantir que a combinação desejada seja validada do início ao fim do texto, caso contrário as extremidades (bordas) do texto poderão conter caracteres indesejadados.
'/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d]$/'
Agora sim, o acento circunflexo ˆ garante que a validação vai ser realizada a partir do primeiro caracter da senha e o dólar $ garante que a combinação desejada será feita até o último caracter da senha.
Regra 3 concluída? Parece que sim, só que não… deixa pa lá, resolvemos depois.
'/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d]{8,36}$/'
Olha que fácil, para determinar as quantidades mínimas e máximas de caracteres basta inserir estes limitadores entre chaves {} sendo o primeiro número a quantidade mínima de caracteres requerida e o segundo número a quantidade máxima requerida.
Parece que a regra está completa, não parece? Então onde está o BUG?
Seguinte, espaços em brancos passam batidos na validação de letras e números, justamente por que espaço em branco não é nada. Não é letra, não é número, não é caracter especial, nada.
'/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z\d].\S{8,36}$/'
Pronto, com o .\S garantimos que espaços em brancos não estejam presentes na senha. Maravilha!
Mas você ainda pode estar se perguntando sobre as barras / no ínicio e fim da máscara e também o recobrimento com as aspas, certo?
O REGEX requer o recobrimento com delimitadores, no meu caso escolhi o mais trivial que são barras normais SLASHES. Mas você poderia utilizar outros caracteres a seu critério como PIPE | ou NUMBER #. O interessante é que você use como delimitador algum caracter que você não vá utilizar na composição da máscara.
Por fim, uma máscara é uma string, assim temos que recobri-la com aspas, que podem ser simples ” ou duplas “”, tanto faz.
Então, gostou do REGEX? Isso é um mundo a parte, pegar proficiência neste campo requer muito empenho mas vale a pena.
Eu nunca encontrei um treinamento que te ensina como pensar em REGEX, mas acho que isso é algo que somente se adquire com tempo e experiência.
Então, boa sorte!