Задать вопрос
@fasewyby

Как правильно вывести ошибки регистрации?

Есть контроллер User. И два метода регистрации - один показывает саму вью, а другой работает с полученными данными:
spoiler
public function register(): void
{
    $page_title = 'Регистрация';
    $this->view->render('/users/register', [
        'page_title' => $page_title
    ], 'default');
}

public function registerStore(): void
{
    $fillable = ['name', 'email', 'password'];
    $data = load_data($fillable);
    $rules = [
        'name' => [
            'required' => true,
            'min' => 3,
            'max' => 20
        ],
        'email' => [
            'required' => true,
            'min' => 5,
            'max' => 20,
            'email' => $data['email'],
            'unique' => 'users:email'
        ],
        'password' => [
            'required' => true,
            'min' => 5,
            'max' => 20
        ]
    ];
    
    $validation = $this->formValidator->validate($data, $rules);
    
    if (!$validation->hasErrors()) {
        $data['password'] = password_hash($data['password'], PASSWORD_BCRYPT);

        $this->model->name = $data['name'];
        $this->model->email = $data['email'];
        $this->model->password = $data['password'];
        
        if ($this->model->save()) {
            redirect('/');
        } else {
            $_SESSION['erros']['flash'] = 'Ошибка регистрации';
            redirect('/users/registerStore');
        }
    } else {
        $_SESSION['errors'] = [];
        $fields = array_keys($validation->getErrors());

        foreach ($fields as $field) {
            $_SESSION['errors'][$field] = $validation->listErrors($field);
        }
        
        redirect('/users/register');
    }
}

Интересует. Как принято делать в таких случаях, когда нужно пользователю сообщить об ошибках, если они есть? Сначала, в случае ошибок регистрации я просто вызывал метод register и передавал в него $validation. Но это показалось мне полным бредом. И я начал писать ошибки в сессию и делать редирект и выводить ошибки во вьюшке. Но теперь старые данные, которые вводил пользователь удаляются. Снова в сессию писать и условные проверки делать? Просто сама вьюшка разрастается. Вот код:
spoiler
<main>
    <?php if (isset($_SESSION['errors']['flash'])): ?>
        <p><?= isset($_SESSION['errors']['flash']) ?></p>
    <?php endif; ?>
   
    <form action="/users/registerStore" method="POST">
        <p>
            Имя: <input type="text" name="name" value="<?= htmlspecialchars($_POST['name'] ?? '') ?>">
            <?= isset($_SESSION['errors']['name']) ? $_SESSION['errors']['name'] : '' ?>
        </p>
        <p>
            Email: <input type="text" name="email" value="<?= htmlspecialchars($_POST['email'] ?? '') ?>">
            <?= isset($_SESSION['errors']['email']) ? $_SESSION['errors']['email'] : '' ?>
        </p>
        <p>
            Пароль: <input type="password" name="password" value="<?= htmlspecialchars($_POST['password'] ?? '') ?>">
            <?= isset($_SESSION['errors']['password']) ? $_SESSION['errors']['password'] : '' ?>
        </p>
        <p><button type="submit">Зарегистрироваться</button></p>

        <?php unset($_SESSION['errors']) ?>
    </form>
</main>
  • Вопрос задан
  • 211 просмотров
Подписаться 2 Простой 10 комментариев
Пригласить эксперта
Ответы на вопрос 2
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Просто сама вьюшка разрастается.


Такова жизнь. Вью - это логика представления. Вот логику мы и добавляем. И это ещё цветочки, бывает куда больше.

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

foreach ($rules as $key => $throwaway) {
    $errors[$key] = $_SESSION['errors'][$key] ?? '';;
    $input[$key] = $_POST[$key] ?? $_SESSION['input'][$key] ?? '';
}
unset($_SESSION['errors'], $_SESSION['input']);


И в шабалоне уже ничего не проверять

<p>
    Имя: <input type="text" name="name" value="<?= h($input['name']) ?>">
    <?= h($errors['name']) ?>
</p>


И сделаю одно замечание. У вас при выводе в HTML экранируются не все значения. А должны - все.
Чтобы не ломать пальцы, набирая htmlspecialchars каждый раз, сделать функцию-хелпер.
Ответ написан
@galliard
Все ваши проблемы выросли из-за того, что у вас 2 экшна. Завертите все в один, а там напишите If. Примерно как-то так
if (пришли_регистрационные_данные) {
    if (данные_валидны) {
        зарегистроровать(данные)
        return сделать_редирект(куда)
    }

    return показать_шаблон(данные, ошибки)
}

return показать_шаблон()
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы