PHP Profi

Валидация массива формы в Laravel 5.2 Перевод Серия 

php Laravel 5.2 form array validation валидация массив форма

В этой серии я хочу рассказать о новых возможностях Laravel 5.2. Вы заметите, что многое из этого функционала быстрее и легче изучить и использовать, так что может показаться, что этот релиз намного меньше предыдущих. Многое из 5.2 связано с простотой и удобством кода, который мы пишем изо дня в день.

Краткое введение в массивы HTML-формы

Валидация массива формы упрощает процесс проверки немного нестандартной формы данных передаваемых в HTML-форму — когда используется синтаксис массива. Например, распространенный случай, когда пользователь может добавить несколько экземпляров одного типа на одной форме...

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

Вот наш HTML; представьте себе, что у нас есть некоторый JavaScript, который создает новый div "employee" ("сотрудник") каждый раз, когда вы нажимаете кнопку "Add another employee" ("добавить еще одного сотрудника"), так что пользователь может добавить столько человек, сколько хочет.

<form>
    <label>Company Name</label>
    <input type="text" name="name">

    <h3>Employees</h3>
    <div class="add-employee">
        <label>Employee Name</label>
        <input type="text" name="employee[1][name]">
        <label>Employee Title</label>
        <input type="text" name="employee[1][title]">
    </div>
    <div class="add-employee">
        <label>Employee Name</label>
        <input type="text" name="employee[2][name]">
        <label>Employee Title</label>
        <input type="text" name="employee[2][title]">
    </div>
    <a href="#" class="js-create-new-add-employee-box">Add another employee</a>

    <input type="submit">
</form>

Если вы заполните эту форму и отправите её, то $_POST-данные этой формы будут такие:

array(2) {
  ["name"]=>
  string(10) "Acme, Inc."
  ["employee"]=>
  array(2) {
    [1]=>
    array(2) {
      ["name"]=>
      string(10) "Joe Schmoe"
      ["title"]=>
      string(11) "Head Person"
    }
    [2]=>
    array(2) {
      ["name"]=>
      string(18) "Conchita Albatross"
      ["title"]=>
      string(21) "Executive Head Person"
    }
  }
}

Как вы можете видеть, мы получаем "объект" employee, который содержит массив переданных идентификаторов с парами ключ/значение в формате "имя поля" => "значение поля, заполненное пользователем".

Примечание: распространённой ошибкой является то, что чтобы задать поле "employee name" просто используют employee[][name] без установки ID вручную. Не делайте этого! Это сделает работу с кодом более сложной.

Но как нам валидировать это? До 5.2, это куча ручной работы. Теперь Laravel понимает такую вложенную структуру и может валидировать внутренние элементы.

Пишем правила валидации массива формы

Итак, как нам это сделать? Давайте взглянем на обычный валидатор:

// CompaniesController.php
    public function store(Request $request)
    {
        $this->validate($request->all(), [
            'name' => 'required|string'
        ]);
        // Save, etc.
    }

А теперь давайте добавим проверку для наших полей сотрудника компании:

// CompaniesController.php
    public function store(Request $request)
    {
        $this->validate($request->all(), [
            'name' => 'required|string',
            'employee.*.name' => 'required|string',
            'employee.*.title' => 'string',
        ]);
        // Save, etc.
    }

Теперь мы проверяем каждые уникальные employee[*][name] и employee[*][title] однозначно, с практически нулевыми усилиями с нашей стороны. Красота!

Постскриптум

Вы, наверное, заметили, что форма записи валидации - employee.*.name, — со звездочкой в середине, которая практически означает, что вы могли бы поставить на её место что-то еще.

Что, если вместо звездочки, обозначающей "все", вы ставите какие-то конкретные числа? Оказывается, это валидация записи только с таким идентификатором. Так что если вы ставите employee.1.name в правило валидации массива вместо employee.*.name, то только сотрудник с ID 1 будет проверяться в соответствии с этими правилами.

Я не знаю почему или когда вам понадобилось бы сделать что-то подобное, но на самом деле вы можете задать совершенно отдельные правила валидации для каждого ID:

$this->validate($request->all(), [
        'employee.1.name' => 'required|string',
        'employee.2.name' => 'integer', // Не уверен *зачем* вам это, но это возможно
    ]);

Вот и всё. Наслаждайтесь!

2016-04-27 alek13 Поделиться: оригинал