HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Создание сущности в CRUD требует наличия двух маршрутов: один для отображения формы, другой для обработки формы. Кроме того, важно понимать как взаимодействуют между собой эти маршруты, как обрабатываются ошибки и так далее. Начнем с того что у нас есть три состояния:</p>
1 <p>Создание сущности в CRUD требует наличия двух маршрутов: один для отображения формы, другой для обработки формы. Кроме того, важно понимать как взаимодействуют между собой эти маршруты, как обрабатываются ошибки и так далее. Начнем с того что у нас есть три состояния:</p>
2 <ul><li>Отображение новой формы</li>
2 <ul><li>Отображение новой формы</li>
3 <li>Отображение формы с подсвеченными ошибками валидации после ее отправки</li>
3 <li>Отображение формы с подсвеченными ошибками валидации после ее отправки</li>
4 <li>Редирект на какую-то страницу (обычно это редактирование сущности или список сущностей) после успешной обработки формы</li>
4 <li>Редирект на какую-то страницу (обычно это редактирование сущности или список сущностей) после успешной обработки формы</li>
5 </ul><p>Самое интересное здесь - вторая часть. Когда данные формы приходят в обработчик формы (пользователь нажал кнопку отправки), этот обработчик выполняет "валидацию", то есть проверку введенных данных. Например, проверяет, что данные в принципе есть, то есть они не пустые. Если данные корректные, то обработка завершается и пользователя отправляют в другое место, но если нет, то Laravel должен отработать эту ситуацию по особенному.</p>
5 </ul><p>Самое интересное здесь - вторая часть. Когда данные формы приходят в обработчик формы (пользователь нажал кнопку отправки), этот обработчик выполняет "валидацию", то есть проверку введенных данных. Например, проверяет, что данные в принципе есть, то есть они не пустые. Если данные корректные, то обработка завершается и пользователя отправляют в другое место, но если нет, то Laravel должен отработать эту ситуацию по особенному.</p>
6 <p>С точки зрения пользователя, это выглядит просто. Сайт снова отображает форму с подставленными значениями, которые он ввел раньше. Кроме этого, на странице выводятся возникшие ошибки. Дальше пользователь их исправляет и отправляет форму заново. Этот процесс может повторяться много раз перед тем, как пользователь сделает все правильно.</p>
6 <p>С точки зрения пользователя, это выглядит просто. Сайт снова отображает форму с подставленными значениями, которые он ввел раньше. Кроме этого, на странице выводятся возникшие ошибки. Дальше пользователь их исправляет и отправляет форму заново. Этот процесс может повторяться много раз перед тем, как пользователь сделает все правильно.</p>
7 <p>Технически Laravel ведет себя так. Если пользователь ввел что-то некорректно, то происходит редирект на страницу с формой. Laravel автоматически записывает данные формы в сессию, а затем использует эти данные для подстановки в форму (тут участвует formModel()).</p>
7 <p>Технически Laravel ведет себя так. Если пользователь ввел что-то некорректно, то происходит редирект на страницу с формой. Laravel автоматически записывает данные формы в сессию, а затем использует эти данные для подстановки в форму (тут участвует formModel()).</p>
8 <h2>Форма</h2>
8 <h2>Форма</h2>
9 <p>Как обычно, нам придется добавить три вещи: маршрут, обработчик маршрута, шаблон.</p>
9 <p>Как обычно, нам придется добавить три вещи: маршрут, обработчик маршрута, шаблон.</p>
10 <h3>Маршрут</h3>
10 <h3>Маршрут</h3>
11 <p>Важно добавить этот маршрут до маршрута<em>articles/{id}</em>. Иначе последний перехватит обращение к<em>articles/create</em>, так как он соответствует шаблону.</p>
11 <p>Важно добавить этот маршрут до маршрута<em>articles/{id}</em>. Иначе последний перехватит обращение к<em>articles/create</em>, так как он соответствует шаблону.</p>
12 <h3>Обработчик</h3>
12 <h3>Обработчик</h3>
13 <h3>Шаблон</h3>
13 <h3>Шаблон</h3>
14 <h2>Обработчик данных формы</h2>
14 <h2>Обработчик данных формы</h2>
15 <h3>Маршрут</h3>
15 <h3>Маршрут</h3>
16 <h2>Обработчик</h2>
16 <h2>Обработчик</h2>
17 <p>В данном обработчике нам понадобился доступ к объекту запроса. Любая информация о HTTP-запросе, любые данные, отправленные по HTTP, можно получить только через $request.</p>
17 <p>В данном обработчике нам понадобился доступ к объекту запроса. Любая информация о HTTP-запросе, любые данные, отправленные по HTTP, можно получить только через $request.</p>
18 <p><em>Как и раньше тут может возникнуть вопрос, каким образом Laravel понимает что в этот метод надо передать объект запроса, а в другие ничего передавать не надо. Ответ кроется в метапрограммировании, которое в PHP делается через<a>Reflection API</a>.</em></p>
18 <p><em>Как и раньше тут может возникнуть вопрос, каким образом Laravel понимает что в этот метод надо передать объект запроса, а в другие ничего передавать не надо. Ответ кроется в метапрограммировании, которое в PHP делается через<a>Reflection API</a>.</em></p>
19 <p>Первым делом объект $request используется в валидации. Валидация в Laravel привязана к запросу. Она выполняется с помощью метода validate($request, $params), доступного в каждом контроллере. Второй аргумент в этом методе - массив, в котором ключ это название поля из формы, а значение, это набор "валидаторов", правил, которые применяются к значению для проверки его корректности. Валидаторы отделяются друг от друга вертикальной чертой. Вот что они означают:</p>
19 <p>Первым делом объект $request используется в валидации. Валидация в Laravel привязана к запросу. Она выполняется с помощью метода validate($request, $params), доступного в каждом контроллере. Второй аргумент в этом методе - массив, в котором ключ это название поля из формы, а значение, это набор "валидаторов", правил, которые применяются к значению для проверки его корректности. Валидаторы отделяются друг от друга вертикальной чертой. Вот что они означают:</p>
20 <ul><li><em>required</em>- не может быть пустым</li>
20 <ul><li><em>required</em>- не может быть пустым</li>
21 <li><em>min:1000</em>- минимум 1000 символов</li>
21 <li><em>min:1000</em>- минимум 1000 символов</li>
22 <li><em>unique:articles</em>- поле (<em>name</em>) должно быть уникально в таблице<em>articles</em></li>
22 <li><em>unique:articles</em>- поле (<em>name</em>) должно быть уникально в таблице<em>articles</em></li>
23 </ul><p>Метод validate ничего не делает, если с данными все в порядке, и выбрасывает исключение в случае ошибок. Затем Laravel перехватывает это исключение и выполняет всю остальную работу за нас. Он сохраняет данные формы, делает редирект на страницу отображения формы и формирует переменную $errors, доступную в шаблоне. Самый простой способ вывести ошибки, добавить над формой такой код:</p>
23 </ul><p>Метод validate ничего не делает, если с данными все в порядке, и выбрасывает исключение в случае ошибок. Затем Laravel перехватывает это исключение и выполняет всю остальную работу за нас. Он сохраняет данные формы, делает редирект на страницу отображения формы и формирует переменную $errors, доступную в шаблоне. Самый простой способ вывести ошибки, добавить над формой такой код:</p>
24 <p>Вернемся к нашему обработчику. Сразу после валидации выполняется создание сущности, наполнение ее данными формы и сохранение.</p>
24 <p>Вернемся к нашему обработчику. Сразу после валидации выполняется создание сущности, наполнение ее данными формы и сохранение.</p>
25 <p>Метод fill($params) выполняет, так называемый<a>mass-assignment</a>, то есть установку сразу всех значений через передачу ассоциативного массива. Такой способ удобнее чем копировать каждое значение индивидуально:</p>
25 <p>Метод fill($params) выполняет, так называемый<a>mass-assignment</a>, то есть установку сразу всех значений через передачу ассоциативного массива. Такой способ удобнее чем копировать каждое значение индивидуально:</p>
26 <p>Но mass-assignment обладает одним недостатком, который приходится обрабатывать отдельно. Такой способ установки значений опасен, так как пользователь может послать любые данные, включая те, которых нет в форме (это HTTP, пользователь может отправить все что угодно). Это значит, что пользователь может переписать любые данные, к которым он может не иметь доступа. Это могут быть пароли, идентификаторы и приватные данные.</p>
26 <p>Но mass-assignment обладает одним недостатком, который приходится обрабатывать отдельно. Такой способ установки значений опасен, так как пользователь может послать любые данные, включая те, которых нет в форме (это HTTP, пользователь может отправить все что угодно). Это значит, что пользователь может переписать любые данные, к которым он может не иметь доступа. Это могут быть пароли, идентификаторы и приватные данные.</p>
27 <p>Разные фреймворки обрабатывают эту ситуацию по-разному. Laravel предлагает создавать внутри модели массив, в котором перечисляются поля, доступные для mass-assignment. Все, что там не перечислено, будет игнорироваться:</p>
27 <p>Разные фреймворки обрабатывают эту ситуацию по-разному. Laravel предлагает создавать внутри модели массив, в котором перечисляются поля, доступные для mass-assignment. Все, что там не перечислено, будет игнорироваться:</p>
28 <p>Это легко проверить в Tinker:</p>
28 <p>Это легко проверить в Tinker:</p>
29 <p>После того как объект сохранился в базе данных, осталось перенаправить пользователя в то место, куда мы хотим его отправить после успешного создания. Обычно отправка идет на список сущностей или страницу редактирования.</p>
29 <p>После того как объект сохранился в базе данных, осталось перенаправить пользователя в то место, куда мы хотим его отправить после успешного создания. Обычно отправка идет на список сущностей или страницу редактирования.</p>
30 <p>Обратите внимание, что у обработчика данных формы нет своего шаблона. Он в любом случае выполняет редирект: либо на исходную форму, либо на результирующую.</p>
30 <p>Обратите внимание, что у обработчика данных формы нет своего шаблона. Он в любом случае выполняет редирект: либо на исходную форму, либо на результирующую.</p>