Easiest way: Return NULL if the validation passed, and the error message if it failed. Prevents the need to make Error classes or exceptions. Also the best for performance.
eg.
function numeric($input) {
if (!is_numeric($input)) return 'Must be numeric.';
return NULL;
}
function usernameavailable($input) {
//query database....
if ($result) return 'Username already taken, please choose another one.';
return NULL;
}
You can use functions with parameters as well:
function length($input, $min, $max) {
if (strlen($input) < $min) return "Must be longer than $min characters.";
if (strlen($input) > $max) return "Must be shorter than $max characters.";
return NULL;
}
Validating the each element in the entire form is then extremely easy. Just loop over all the elements, call all the validation functions for that element and collect the error strings, if any. If there are no error strings, then all the user input is valid.
I would strongly discourage the suggestions made by one of the other answers. Invalid user input is not Exceptional and does not require an exception or an error. It's simply an expected use case that has to be dealt with in the simplest possible manner.
With this method, you can build a Form class quite easily and simply instantiate elements with the arguments being the validation functions. You can also expand this to include AJAX validation sending asynchronous requests to the exact same PHP validation functions.
Example from my framework:
$Form = new AjaxForm();
$Form->add(new TextBox('Username', 'usernameavailable|length[3,12]'));
$Form->add(new SubmitButton());
With only three lines I've created a fully functional form with both client side and server side validation. Of course all the details are up to you but I still believe that invalid user input should be expected and not be Exceptional.