Проверка наличия ошибки после выполнения валидации


Исходный код

$error = "Всё хорошо";
 
if (!$_POST['mail'] || !checkEmail($_POST['mail'])) {
    $error .= "Не верный E-mail";
}
 
if ($error == "Всё хорошо") {

Что не так в этом коде

1) Странный способ хранить результат валидации входных данных.

Почему он странный.

В данном конкретном примере валидируется всего одно поле (электронный адрес) и используется всего два состояния: «порядок» или «не порядок». Поэтому для этого конкретного случая нет смысла хранить признак в виде строки, достаточно булева значения.

2) В PHP рекомендуется использовать строгое сравнение === из-за неожиданного поведения правил неявного приведения типов:

if ($error === "Всё хорошо") {

Что можно улучшить

1. Присваивать переменной $error значения true и false:

$error = false;
 
if (!$_POST['mail'] || !checkEmail($_POST['mail'])) {
    $error = true;
}
 
if ($error) {

Дальше первые две операции можно записать короче:

$error = !$_POST['mail'] || !checkEmail($_POST['mail']);
if ($error) {

2. Использовать массив для хранения результата валидации

Практика показывает, что там, где есть одно поле входных данных, легко может появиться и второе, и десятое.

Предполагаю, что в оригинале данного примера изначально так и было, поэтому автору кода не хватило булева значения, а получаемые результаты валидации каждого поля добавлялись к исходной строке.

Такой способ хранения результатов валидации не даёт никаких возможностей для их дальнейшего более-менее сложного использования, поэтому полезнее для результатов валидации использовать массив:

$errors = [];

if (!$_POST['mail']) || !checkEmail($_POST['mail'])) {
    $errors['email'][] = 'Не верный E-mail';
}

if (!empty($errors)) {

3. Фиксировать по отдельности результаты каждого вида проверки:

$errors = [];

if (!$_POST['mail'])) {
    $errors['email'][] = 'Не указан E-mail';
}
if (!checkEmail($_POST['mail'])) {
    $errors['email'][] = 'Неправильный E-mail';
}

if (!empty($errors)) {

Это позволяет сообщать пользователю полее понятную информацию о допущенных ошибках при заполнении формы. Даже если ты делаешь API, подробное сообщение важно для программиста, который будет работать с этим API.

Операция $errors['email'][] = позволяет зафиксировать сразу несколько ошибочных ситуаций, обнаруженных в проверяемом значении.

Например, при проверке пароля ты можешь обнаружить, что он слишком короткий и одновременно содержит недопустимые символы.

4. Расширить информацию об ошибке

$errors = [];

if (!$_POST['mail'])) {
    $errors['email'][] = [ 'type' => 'empty', 'message' => 'Не указан E-mail' ];
}
if (!checkEmail($_POST['mail'])) {
    $errors['email'][] = [ 'type' => 'invalid', 'message' => 'Неправильный E-mail' ];
}

if (!empty($errors)) {

В таком виде информация об ошибке пригодна и для машинной обработки, и для показа обычному пользователю.