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?
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:
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With