Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to validate users input? [closed]

I am developing a new application using object oriented approach with some REST involved, I am not using any frameworks.

The question I have is where is the best place to validate a user’s input in a setter like below:

public function setSalary($salary)
{
    if (Validator::money($salary))
        $this->salary = $salary;
    else
        return 'Error that is an invalid number';
}

Or in the controller?

public function updateSalary()
{
    $errors = array();

    if (Validator::money($_POST['salary']))
        $salary = $_POST['salary'];
        else
            $errors ['salary']  = 'Error that is an invalid number';

    if(count($errors))
        return $errors;

    $employee = new Employee($_POST['e_Id']);
    $employee->setSalary($salary);

    $employee->save();
}

If I was to put in the setter how should my controller look, and return validation errors?

I have seen most people do validation in the controller, however I think should be the models responsibility for validation as it going to be using the data, and we can reuse that model without repeating ourselves. However there can be times when validation rules may need to be different in some special cases like different validation for a different view or different validation for a supper admin.

Which one would you say is in accordance with best practices?

like image 433
ffmsingh Avatar asked Mar 25 '16 11:03

ffmsingh


1 Answers

First of all, since you seem to aspire to implement MVC-like structure, lets start by some general mistakes, that are not related to validation directly.

  • Only part of your code, containing PHP superglobals, should be the bootstrap stage. Having superglobals sprinkled all over your code makes it really hard to test. And your code also becomes tightly couple to your HTML, via the <input> names.

  • Even if your for or if statement contains a single line, you should always use curly brackets. Well, in general your code should follow the PSR-1 and PSR-2 guidelines.

  • Controllers should not have any logic, or be dealing with saving of data. Read this post, maybe it clears some things up.

Ok .. now back to the original subject.

In general there are two schools of thought:

  1. You do the validation in the domain entity

    Your domain entity (in your case Employee) contains all the business roles, that pertain to it. And it can use those rules to assess, if it is in a valid state.

    The code would go something like this:

    $employee = new Entity\Employee;
    $employee->setID($id);
    $employee->setSalary($money);    
    if ($employee->isValid()) {
        $mapper = new Mapper\Employee($dbConn);
        $mapper->store($emplyee);
    }
    
  2. You never create invalid domain entity

    This approach comes from DDD, where you domain entity is created by some other class and it can only be changes from one valid state to another valid state. Essentially, if you want to explore this approach, you will have to read this book (probably several times).

Also, there is one other validation form, which is note covered by the previous two: data integrity checks. This is type of validation, that is actually done my RDBMS. For example, the UNIQUE constraints.

When you encounter ans integrity violation, it usually would throw an exception, that you handle in service layer.

like image 96
tereško Avatar answered Sep 25 '22 02:09

tereško