php – How to consume validation function?

Question:

For didactic reasons, I created a function in php to validate 3 fields, the function is in the validate.php file:

<?php
/**
 * Created by PhpStorm.
 * User: Jorge
 * Date: 01/06/2018
 * Time: 10:40
 */


function valida($nome, $senha, $email) {

$error = [
        'nome' => 'Não é permitido caracteres especiais nem espaços em branco!',
        'senha' => 'Não é permitido caracteres especiais nem espaços em branco!',
        'email' => 'E-mail incorreto'
       ];
if (!preg_match("/^[a-zA-Z ]*$/", $nome)) {
    $error["nome"];
    exit;
}

if (!preg_match("/^[a-zA-Z ]*$/", $senha)) {
    $error["senha"];
    exit;
}

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $error["email"];
    exit;
}

 return $error;
}

In my controller I'm using it like this, but I know it's not correct:

<?php
/**
 * Created by PhpStorm.
 * User: Jorge
 * Date: 30/05/2018
 * Time: 17:36
 */

require "../models/Connection.php";
require "validate.php";

$errorNome = '';
$errorSenha = '';
$errorEmail = '';
if (isset($_POST["username"]) && !empty($_POST["username"])) {
    $user = $_POST["username"];
    $email = $_POST["email"];
    $pass = password_hash($_POST["password"], PASSWORD_DEFAULT);

    if (valida($user, $pass, $email)) {
       $errorNome = $error["nome"];
       $errorPass = $error["senha"];
       $errorEmail = $error["email"];
       header("location: ../views/add.php");
    }
    else {

    $pdo = $pdo->prepare("INSERT INTO users (nome, email, senha) VALUES (?, ?, ?)");
        $pdo->bindParam(1, $user);
        $pdo->bindParam(2, $email);
        $pdo->bindParam(3, $pass);
        $pdo->execute();

        if ($pdo->rowCount() > 0) {
            echo "sucesso!";
        }
    }
}

In the view is as follows:

 require "../controllers/addUserController.php"; ?> <html> <head> </head> <body> <form action="../controllers/addUserController.php" method="POST"> <input type="text" placeholder="Username" name="username"> <span> <?=$errorNome?> </span> <input type="text" placeholder="E-mail" name="email"> <span> <?=$errorEmail?> </span> <input type="password" placeholder="Password" name="password"> <span> <?=$errorSenha?> </span> <input type="submit" value="Cadastrar"> </form> </body> </html>

My question is, how do I allow the insertion into the database only if everything is correct as defined in the function? And if any field is wrong, how do I show the error message?

Is this the correct way to perform a check? If not, what would be a good option?

Thank you all for the attention.

Answer:

Some adaptations are needed for your example to work the way it's organized. First, your valida() function should return different things, whether or not there are errors, an example would be:

validity.php

<?php

/**
 * @return string|null caso haja algum erro de validação retorna
 * um array de strings descrevendo os erros 
 * é retornado, caso não haja erros de validação, retorna null;
 * 
*/
function valida($nome, $senha, $email) {

    $error = [
            'nome' => 'Não é permitido caracteres especiais nem espaços em branco!',
            'senha' => 'Não é permitido caracteres especiais nem espaços em branco!',
            'email' => 'E-mail incorreto'
           ];

    $errosEncontrados = [];

    if (!preg_match("/^[a-zA-Z ]*$/", $nome)) {
        $errosEncontrados['nome'] = $error["nome"];
    }

    if (!preg_match("/^[a-zA-Z ]*$/", $senha)) {
        $errosEncontrados['nome'] = $error["senha"];
    }

    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errosEncontrados['nome'] = $error["email"];
    }

    //verifica o tamanho do vetor $errosEncontrados
    if(count($errosEncontrados) > 0){
        return $errosEncontrados;
    }

    return null;
}

With these changes in the valid function, it is possible to check in the controller if the fields passed validation or not. In the controller you need to make some changes (in the comments for more details):

in your controller.php

<?php
//......
$pass = password_hash($_POST["password"], PASSWORD_DEFAULT);

    //vetor com os erros retornados pela função valida
    //ou null caso não existam
    $erros = valida($user, $pass, $email);
    if ($erros !== null) {
       $errorNome = $errors["nome"];
       $errorPass = $errors["senha"];
       $errorEmail = $errors["email"];
       //se você fizem um header location, essas variaveis não existiram 
       //mais na nova requisição.
       //header("location: ../views/add.php");

       //é mais adequado usar um require ou include, nesse caso
       //nada mais deveria ser impresso, além do que está dentro de add.php
       require '../views/add.php';
       //então faça um exite para garantir que apenas o conteudo do 
       //arquivo incluido seja retorndado para o navegador
       exit;
    }
    else {

    $pdo = $pdo->prepare("INSERT INTO users (nome, email, senha) VALUES (?, ?, ?)");
        $pdo->bindParam(1, $user);
        $pdo->bindParam(2, $email);
        $pdo->bindParam(3, $pass);
        $pdo->execute();
//.......

Here there were only two changes, one to check for validation errors, and the other related to header location, which would not work as expected.

In your view it should work as expected, unless the add.php file is called without the variables used in it having been declared before. To avoid this possible problem, just change the occurrences of <?=$errorEmail?> to .

An alternative would be for you to use some validation library, such as respect

Scroll to Top