Привет, Хаброжители!
Что отличает Laravel от других PHP-фреймворков? Скорость и простота. Стремительная разработка приложений, обширная экосистема и набор инструментов Laravel позволяют быстро создавать сайты и приложения, отличающиеся чистым удобочитаемым кодом. Третье издание, обновленное с учетом Laravel 10, — это практическое руководство по использованию одного из самых популярных на сегодняшний день веб-фреймворков.
Мэтт Стаффер, известный преподаватель и ведущий разработчик, представляет полный обзор фреймворка и конкретные примеры работы с ним. Опытным PHP-разработчикам книга поможет быстро разобраться с темой, чтобы реализовать проект на Laravel. В обновленном руководстве рассматриваются в том числе совершенно новые инструменты аутентификации и разработки пользовательских интерфейсов, а также ряд сторонних инструментов, появившихся после выхода в свет второго издания.
Современные PHP-фреймворки предполагают, что многие взаимодействия с ними будут осуществляться из командной строки. Для этого Laravel предоставляет три основных инструмента: Artisan — набор встроенных действий командной строки с возможностью расширения; Tinker — интерактивная оболочка REPL для вашего приложения; мастер установки, который мы уже рассмотрели в главе 2.
Вы уже научились использовать команды Artisan. Они выглядят примерно так:
Если заглянуть в корневую папку своего приложения, то можно заметить, что artisan на самом деле является файлом PHP. Поэтому, запуская команду, начинающуюся с php artisan, вы вызываете интерпретатор PHP и передаете ему файл artisan для выполнения. Все, что следует далее, просто передается в Artisan в виде аргументов.
Список команд Artisan для приложения может меняться в зависимости от пакета или конкретного кода приложения. Поэтому всегда стоит исследовать каждое новое приложение, с которым вы сталкиваетесь, чтобы узнать, какие команды в нем доступны.
Для этого можно запустить php artisan list из корня проекта. Простая команда php artisan без параметров выведет то же самое.
Здесь недостаточно места, чтобы описать все команды Artisan, но мы рассмотрим многие из них. Начнем с основных.
Удаляет файл скомпилированного класса Laravel, который похож на внутренний кэш Laravel. Применяйте, когда что-то не так, но вы не знаете почему.
Переводит ваше приложение в режим обслуживания, чтобы вы могли исправить ошибку, запустить миграции или сделать что-то еще, и выводит из режима обслуживания соответственно.
Запускает сервер дампа (см. раздел «Сервер дампа Laravel» далее в главе) для сбора и вывода загруженных переменных.
Показывает, в какой среде Laravel работает в данный момент. Эквивалентно выводу app()->environment() в приложении.
Выводит справку для команды, например php artisan help commandName.
Запускает все миграции базы данных.
Очищает и обновляет файлы конфигурации и маршрута.
Привязывает PHP-сервер к адресу localhost:8000. Хост и/или порт можно настроить с помощью параметров --host и --port.
Запускает интерактивную оболочку Tinker REPL, о которой я расскажу позже в этой главе.
Публикует все заглушки, доступные для настройки.
Дает быстрый доступ к документации Laravel. Если передать этой команде параметр, то она предложит открыть URL с запрошенным документом, в противном случае вы получите возможность перемещаться по списку тем в документации.
Выводит обобщенную информацию о среде проекта, конфигурации, пакетах и многом другом.
Рассмотрим несколько важных параметров, которые можно передавать любым командам Artisan.
Подавляет весь вывод.
Позволяет установить уровень детализации вывода (нормальный, подробный и отладочный).
Подавляет интерактивные вопросы, поэтому команда не будет прерывать автоматизированные процессы, выполняющие ее.
Позволяет задать, в какой среде должна работать команда Artisan (локальная, производственная и т. д.).
Показывает, на какой версии Laravel работает ваше приложение.
Команды Artisan во многом подобны базовым командам оболочки: вы можете запускать их вручную, но они также могут функционировать как часть некоторого автоматизированного процесса.
Например, команды Artisan могут пригодиться в сценариях автоматического развертывания. Возможно, вы захотите запускать php artisan config:cache каждый раз, когда развертываете приложение. Флаги наподобие -q и --no-interaction обеспечивают бесперебойную работу сценариев развертывания без участия человека.
Остальные команды, доступные сразу же «из коробки», сгруппированы по контексту. Мы не будем рассматривать их все, но я расскажу о каждом контексте в общих чертах.
В этом контексте имеется только команда auth:clear-resets, которая обновляет все токены сброса пароля с истекшим сроком действия в базе данных.
cache:clear очищает кэш, cache:forget удаляет отдельный элемент из кэша, а cache:table создает миграцию базы данных, если вы планируете использовать драйвер кэша database.
config:cache кэширует ваши настройки конфигурации для быстрого поиска. Чтобы очистить кэш, используйте config:clear.
db:seed заполняет вашу базу данных, если вы настроили наполнители БД.
event:list выводит список всех событий и прослушивателей в приложении, event:cache кэширует этот список, event:clear очищает кэш, а event:generate создает недостающие файлы событий и слушателей на основе определений в EventServiceProvider. Вы узнаете больше о событиях в главе 16.
key:generate создает случайный ключ шифрования для приложения в вашем файле .env.
Каждое действие make: создает отдельный элемент и принимает соответствующие параметры. Чтобы узнать больше о параметрах любой отдельной команды, используйте help для получения соответствующей справки о команде.
Запустив php artisan help make:migration, вы узнаете, что можно передать параметр --create=tableNameHere и создать миграцию с кодом создания таблицы, например, так: php artisan make:migration create_posts_table --create=posts.
Об этой команде для запуска всех миграций уже рассказывалось ранее; подробные сведения обо всех командах, связанных с миграцией, смотрите в подразделе «Запуск миграций» в главе 5.
notifications:table генерирует миграцию, которая создает таблицу для уведомлений базы данных.
В Laravel есть манифест, созданный функцией автоматического обнаружения. В нем регистрируются сторонние пакеты при их первой установке. package:discover перестраивает обнаруженный манифест сервис-провайдеров Laravel из ваших внешних пакетов.
Мы поговорим об очередях Laravel в главе 16, но основная идея в том, что вы можете помещать задания работнику в удаленные очереди для выполнения по порядку. Эта группа команд предоставляет инструменты взаимодействия с очередями, такие как queue:listen для начала прослушивания очереди, queue:table для создания миграции для очередей, поддерживаемых базой данных, и queue:flush для сброса всех неудачных заданий очереди. Об этом и многом другом вы узнаете в главе 16.
Если вы запустите route:list, то увидите определения всех маршрутов в приложении, включая команду/команды каждого маршрута, путь, имя, действие контроллера/замыкания и промежуточное ПО. Вы можете кэшировать определения маршрутов для быстрого поиска с помощью route:cache и очищать кэш с помощью route:clear.
Мы расскажем о cron-подобном планировщике Laravel в главе 16, но для его работы необходимо настроить запуск schedule:run раз в минуту в системном планировщике cron:
Эта команда Artisan предназначена для регулярного запуска и поддержки основного сервиса Laravel.
session:table создает миграцию для приложений, использующих сессии, которые хранятся в базе данных.
storage:link создает символическую ссылку из public/storage в storage/app/public. Это общее соглашение в приложениях Laravel, позволяющее размещать выгружаемые пользователями данные (или другие файлы, которые обычно попадают в storage/app) там, где они будут достижимы по публичному URL-адресу.
Некоторые специфичные для Laravel пакеты должны «публиковать» кое-какие из своих ресурсов, чтобы они могли обслуживаться из вашего каталога public или чтобы вы могли изменять их. В любом случае данные пакеты регистрируют эти «публичные ресурсы» в Laravel. Когда вы запускаете команду vendor:publish, она публикует их в специфичных для них местах.
Движок визуализации Laravel автоматически кэширует ваши представления. Обычно он хорошо справляется со своевременной очисткой кэша, но, если вы когда-нибудь заметите, что он застрял, запустите view:clear для очистки кэша.
Теперь, рассмотрев команды Artisan, поставляемые с Laravel, поговорим о написании собственных команд.
Для этого есть команда Artisan. Команда php artisan make:command YourCommandName создаст новую команду Artisan в app/Console/Commands/{YourCommandName}.php.
В первом аргументе этой команде нужно передать имя класса команды, а при желании можно также передать параметр --command, чтобы определить имя команды, которое должно вводиться в терминале (например, appname:action). Попробуем:
В примере 8.1 показан результат.
Пример 8.1. Каркас команды Artisan по умолчанию
Как видите, определить сигнатуру команды, текст справки, отображаемый в списках команд, и поведение команды при выполнении (handle()) совсем не сложно.
Мы еще не рассмотрели почту или Eloquent в этой главе (почта описана в главе 15, а Eloquent — в главе 5), но образец метода handle() в примере 8.2 должен читаться довольно четко.
Пример 8.2. Образец метода handle() для команды Artisan
Теперь каждый раз при запуске php artisan email:newusers эта команда будет находить всех подписавшихся на этой неделе пользователей и отправлять им приветственные письма.
Если вы предпочитаете внедрять свои почтовые и пользовательские зависимости вместо использования фасадов, можно указать их тип в конструкторе команды. И контейнер Laravel внедрит их при создании экземпляра команды.
Взгляните на пример 8.3 — так может выглядеть пример 8.2, но с внедрением зависимостей и переносом поведения в отдельный вспомогательный класс.
Пример 8.3. Та же команда, рефакторинг
Свойство $signature новой команды выглядит так, будто оно может содержать только имя команды. Однако в действительности в нем также определяются аргументы и опции для команды. Существует специальный простой синтаксис, который можно использовать для добавления аргументов и параметров в ваши команды Artisan.
Прежде чем мы углубимся в этот синтаксис, взглянем на пример для некоторого контекста:
Чтобы определить обязательный аргумент, поместите его в фигурные скобки:
Для необязательного аргумента добавьте знак вопроса:
Чтобы сделать аргумент необязательным и задать значение по умолчанию, используйте следующую конструкцию:
Опции похожи на аргументы, но имеют префикс — и могут использоваться без значения. Чтобы добавить простую опцию, заключите ее в фигурные скобки:
Если опция требует значение — добавьте = к ее сигнатуре:
Если вы хотите передать значение по умолчанию, добавьте его после =:
Чтобы позволить передавать массивы в аргументах и опциях, используйте символ *:
В примере 8.4 показано, как передать массив в виде аргумента и опции.
Пример 8.4. Использование синтаксиса массива с командами Artisan
Встроенные команды Artisan могут сообщать дополнительную информацию о своих параметрах, если использовать artisan help. Мы в своих командах тоже можем предоставить подобную информацию. Просто добавьте двоеточие и текст описания в фигурных скобках, как в примере 8.5.
Пример 8.5. Описание аргументов и опций Artisan
Теперь, предусмотрев прием входных данных, мы должны как-то получить их в методе handle() нашей команды. Для этой цели существует два набора методов.
$this->arguments() возвращает массив всех аргументов (первым элементом будет имя команды). $this->argument() при вызове без параметров вернет тот же ответ. Я предпочитаю метод с именем во множественном числе, который лучше читается в коде.
Чтобы получить значение только одного аргумента, передайте имя аргумента в качестве параметра в $this->argument(), как показано в примере 8.6.
Пример 8.6. Использование $this->arguments() в команде Artisan
$this->options() возвращает массив всех опций, включая те, что по умолчанию имеют значение false или null. $this->option() при вызове без параметров вернет тот же ответ. Я предпочитаю метод с именем во множественном числе, который лучше читается в коде.
Чтобы получить значение только одной опции, передайте ее имя в качестве параметра в $this->option(), как показано в примере 8.7.
Пример 8.7. Использование $this->options() в команде Artisan
В примере 8.8 показана команда Artisan, использующая argument() и option() в методе handle().
Пример 8.8. Получение ввода в команде Artisan
Есть еще несколько способов получить пользовательский ввод внутри handle(), и все они предполагают интерактивный ввод информации пользователем во время выполнения вашей команды:
Предлагает пользователю ввести произвольный текст:
Предлагает пользователю ввести произвольный текст, но скрывает ввод с помощью звездочек:
Запрашивает у пользователя ответ «да/нет» и возвращает логическое значение:
Все ответы, кроме y или Y, будут рассматриваться как «нет».
Предлагает пользователю ввести произвольный текст и предоставляет варианты автозаполнения, но позволяет пользователю ввести все, что он захочет:
Предлагает пользователю выбрать один из возможных вариантов. Последний параметр является значением по умолчанию, которое возвращается, если пользователь не сделал выбор:
Последний параметр по умолчанию должен быть ключом массива. Поскольку мы передали неассоциативный массив, элементу Gators назначается ключ 0. При желании можно передать ассоциативный массив с ключами:
Во время выполнения команды могут выводить сообщения пользователю. Например, вызов $this->info() выведет простой текст зеленого цвета:
Также доступны методы comment() (оранжевый), question() (жирный сине-зеленый), error() (жирный красный) и line() (черно-белый) и newLine() (черно-белый).
Обратите внимание, что точные цвета могут варьироваться от машины к машине, но все пытаются соответствовать стандартам для связи с конечным пользователем.
Метод table() упрощает создание таблиц ASCII, заполненных вашими данными. Посмотрите на пример 8.9.
Пример 8.9. Вывод таблиц в командах Artisan
В примере 8.9 есть два набора данных: заголовки и сами данные. Оба содержат две ячейки на строку. Первая ячейка в каждой строке — это имя, а вторая — адрес электронной почты. Таким образом, данные из вызова Eloquent (который ограничивается извлечением только имени и адреса электронной почты) совпадают с заголовками.
В примере 8.10 показан вывод таблицы.
Пример 8.10. Пример вывода таблицы Artisan
Если вы когда-либо запускали npm install, то видели индикатор выполнения. Создадим один в примере 8.11.
Пример 8.11. Индикатор выполнения Artisan
Сначала мы сообщили системе, сколько единиц нам нужно обработать. Может быть, единица — это пользователь, а у вас 350 пользователей. Затем индикатор разделит всю ширину, доступную на вашем экране, на 350 и будет закрашивать 1/350 часть при каждом вызове progressAdvance(). Когда вы закончите, вызовите progressFinish(), чтобы индикатор знал, что должен прекратить отображаться.
Для простоты команды можно определять не как классы, а как замыкания в routes/console.php. Все, о чем рассказывается в текущей главе, в равной степени применимо и к данному способу, с той лишь разницей, что команды определяются и регистрируются в этом файле за один шаг, как показано в примере 8.12.
Пример 8.12. Определение команды Artisan с использованием замыкания
Команды Artisan предназначены для запуска из командной строки, но их также можно вызывать из другого кода.
Самый простой способ — использовать фасад Artisan. Вызвать команду можно с помощью функции Artisan::call() (которая вернет код завершения команды), или поставить команду в очередь, использовав Artisan::queue().
Обе функции принимают два параметра: консольную команду (password:reset) и массив параметров для нее. В примере 8.13 показана работа с аргументами и опциями.
Пример 8.13. Вызов команд Artisan из другого кода
Значения аргументов передаются вместе с их именами, а с опциями без значения можно передавать true или false.
Команды Artisan можно вызывать из других команд, используя $this->call() (действует так же, как Artisan::call()) или $this->callSilent() (действует аналогично, но подавляет вывод). Посмотрите на пример 8.14.
Пример 8.14. Вызов команд Artisan из других команд Artisan
Наконец, можно внедрить экземпляр контракта Illuminate\Contracts\Console\Kernel и использовать его метод call().
Tinker — это интерактивная оболочка REPL, или «прочитать — выполнить — вывести результат — повторить». REPL выводит приглашение, похожее на приглашение командной строки, которое имитирует состояние ожидания вашего приложения. Вы вводите свои команды в REPL, нажимаете Return и ожидаете, пока команда выполнится и на экране появится ответ.
В примере 8.15 приводится короткая выдержка из сеанса работы с оболочкой REPL, чтобы вы могли получить представление о том, как она работает и насколько может быть полезной. После входа в REPL командой php artisan tinker мы получаем приглашение (>>>). Каждый ответ на наши команды выводится в строке, начинающейся с символов =>.
Пример 8.15. Использование Tinker
Мы создали нового пользователя, установили некоторые данные (для безопасности хешировали пароль с помощью bcrypt()) и сохранили их в базе данных. И это реально. Будь это производственное приложение, мы бы просто создали нового пользователя в системе.
Это делает Tinker отличным инструментом для выполнения простых операций с базой данных, апробации новых идей и запуска фрагментов кода, когда трудно найти место для размещения их в исходных файлах приложения.
Tinker работает на Psy Shell (http://psysh.org/). Загляните по этому адресу, чтобы узнать, что еще может предложить Tinker.
Одним из распространенных методов отладки состояния данных во время разработки является использование вспомогательной функции dump() Laravel, которая запускает более красивый var_dump() для всего, что вы ей передаете. Это хорошо, но часто чревато проблемами с представлениями.
В проектах Laravel можно включить сервер дампа Laravel, который будет перехватывать обращения к dump() и отображать вывод в консоли вместо страницы.
Чтобы запустить сервер дампа в локальной консоли, перейдите в корневой каталог проекта и запустите php artisan dump-server:
Теперь попробуйте использовать функцию dump() где-нибудь в вашем коде. Для пробы введите этот код в ваш файл route/web.php:
Без сервера дампов вы увидите в браузере и дамп, и строку «Hello, World!». Но после запуска сервера дампов в браузере появится только строка «Hello, World!». В своей консоли вы увидите, что сервер дампа перехватил вызов dump(), и вы можете исследовать вывод там:
Любые команды Artisan, генерирующие файлы (например, make:model и make:controller), используют файлы-шаблоны, которые команда затем копирует и изменяет, чтобы создать новые файлы. Вы можете настроить эти шаблоны в своих приложениях.
Для этого запустите команду php artisan stub:publish — она опубликует файлы шаблонов в каталог stub/, где вы сможете их настроить.
Зная, как вызывать команды Artisan из кода, вы с легкостью сможете добавить их в свои тесты и проверить правильность любого ожидаемого поведения, как показано в примере 8.16. В наших тестах мы используем метод $this->artisan() вместо Artisan::call(), потому что он имеет тот же синтаксис, но добавляет несколько связанных с тестированием проверок.
Пример 8.16. Вызов команд Artisan из теста
При желании вы можете добавить цепочку проверок к вызову $this->artisan(). Это поможет упростить тестирование команд Artisan и понять не только какое влияние они оказывают на остальную часть вашего приложения, но и как они на самом деле работают. В примере 8.17 приведен образец такого синтаксиса.
Пример 8.17. Проверка ввода и вывода команд Artisan
Команды Artisan являются инструментами командной строки Laravel. Laravel поставляется с несколькими готовыми командами Artisan, но их легко создавать и вызывать из командной строки или собственного кода.
Tinker — это интерактивная оболочка REPL, которая упрощает вход в среду вашего приложения и взаимодействие с реальными кодом и данными, а сервер дампа позволяет отлаживать код без остановки его выполнения.
Более подробно с книгой можно ознакомиться на сайте издательства:
» Оглавление
» Отрывок
По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Для Хаброжителей скидка 25% по купону — Laravel
Что отличает Laravel от других PHP-фреймворков? Скорость и простота. Стремительная разработка приложений, обширная экосистема и набор инструментов Laravel позволяют быстро создавать сайты и приложения, отличающиеся чистым удобочитаемым кодом. Третье издание, обновленное с учетом Laravel 10, — это практическое руководство по использованию одного из самых популярных на сегодняшний день веб-фреймворков.
Мэтт Стаффер, известный преподаватель и ведущий разработчик, представляет полный обзор фреймворка и конкретные примеры работы с ним. Опытным PHP-разработчикам книга поможет быстро разобраться с темой, чтобы реализовать проект на Laravel. В обновленном руководстве рассматриваются в том числе совершенно новые инструменты аутентификации и разработки пользовательских интерфейсов, а также ряд сторонних инструментов, появившихся после выхода в свет второго издания.
Для кого предназначена книга
Книга подойдет для читателя, знающего базовые методы объектно-ориентированного программирования, язык PHP (или по крайней мере общий синтаксис языков C), а также базовые концепции архитектурного паттерна «Модель — представление — контроллер» (Model — View — Controller, MVC) и обработки шаблонов. Если вы никогда не создавали сайт, материал книги может оказаться слишком сложным. Но если у вас есть опыт программирования, то не обязательно знать что-то о Laravel — я объясню все, что нужно, начиная с простейшего примера Hello, world!..
Laravel может работать в любой операционной системе, но приведенные здесь примеры команд оболочки bash проще запускать в Linux/macOS. Пользователям Windows будет сложнее выполнять эти команды и в целом применять современные средства разработки на PHP, однако, следуя инструкциям, вы сможете установить Homestead (виртуальную машину Linux) и запускать все необходимые команды.
Laravel может работать в любой операционной системе, но приведенные здесь примеры команд оболочки bash проще запускать в Linux/macOS. Пользователям Windows будет сложнее выполнять эти команды и в целом применять современные средства разработки на PHP, однако, следуя инструкциям, вы сможете установить Homestead (виртуальную машину Linux) и запускать все необходимые команды.
Структура издания
В этой книге я старался придерживаться хронологического порядка: сначала рассматриваются базовые компоненты, которые вы будете применять в начале создания веб-приложения с помощью Laravel, а затем — менее фундаментальные и реже используемые возможности.
Хотя каждый раздел книги — самостоятельный материал, главы организованы так, чтобы незнакомые с фреймворком пользователи могли эффективно усваивать материал, читая главы по порядку.
Большинство глав заканчивается двумя разделами: «Тестирование» и «Резюме». В них соответственно показывается, как писать тесты для представленных возможностей, и проводится общий обзор рассмотренного материала.
В книге описывается работа с Laravel 10.
Хотя каждый раздел книги — самостоятельный материал, главы организованы так, чтобы незнакомые с фреймворком пользователи могли эффективно усваивать материал, читая главы по порядку.
Большинство глав заканчивается двумя разделами: «Тестирование» и «Резюме». В них соответственно показывается, как писать тесты для представленных возможностей, и проводится общий обзор рассмотренного материала.
В книге описывается работа с Laravel 10.
О третьем издании
Первое издание книги вышло в декабре 2016 года и освещало возможности версий Laravel с 5.1 по 5.3. Во втором издании, вышедшем в апреле 2019 года, дополнительно рассмотрены возможности версий 5.4–5.8, инструментов Laravel Dusk и Laravel Horizon, а также добавлена глава 18, посвященная ресурсам сообщества и дополнительным пакетам Laravel, которые не были охвачены в первых 17 главах. В этом новом издании рассматривается версия Laravel 10, а также новые пакеты Breeze, Jetstream, Fortify, Vite и многое другое.
Интерфейсы Artisan и Tinker
Современные PHP-фреймворки предполагают, что многие взаимодействия с ними будут осуществляться из командной строки. Для этого Laravel предоставляет три основных инструмента: Artisan — набор встроенных действий командной строки с возможностью расширения; Tinker — интерактивная оболочка REPL для вашего приложения; мастер установки, который мы уже рассмотрели в главе 2.
Введение в интерфейс Artisan
Вы уже научились использовать команды Artisan. Они выглядят примерно так:
php artisan make:controller PostsController
Если заглянуть в корневую папку своего приложения, то можно заметить, что artisan на самом деле является файлом PHP. Поэтому, запуская команду, начинающуюся с php artisan, вы вызываете интерпретатор PHP и передаете ему файл artisan для выполнения. Все, что следует далее, просто передается в Artisan в виде аргументов.
Синтаксис консоли Symfony
Artisan фактически работает поверх компонента Symfony Console (https://oreil.ly/7Cb3Y). Поэтому если вы знакомы с командами Symfony Console, то легко разберетесь с Artisan.
Список команд Artisan для приложения может меняться в зависимости от пакета или конкретного кода приложения. Поэтому всегда стоит исследовать каждое новое приложение, с которым вы сталкиваетесь, чтобы узнать, какие команды в нем доступны.
Для этого можно запустить php artisan list из корня проекта. Простая команда php artisan без параметров выведет то же самое.
Основные команды Artisan
Здесь недостаточно места, чтобы описать все команды Artisan, но мы рассмотрим многие из них. Начнем с основных.
clear-compiled
Удаляет файл скомпилированного класса Laravel, который похож на внутренний кэш Laravel. Применяйте, когда что-то не так, но вы не знаете почему.
down, up
Переводит ваше приложение в режим обслуживания, чтобы вы могли исправить ошибку, запустить миграции или сделать что-то еще, и выводит из режима обслуживания соответственно.
dump-server
Запускает сервер дампа (см. раздел «Сервер дампа Laravel» далее в главе) для сбора и вывода загруженных переменных.
env
Показывает, в какой среде Laravel работает в данный момент. Эквивалентно выводу app()->environment() в приложении.
help
Выводит справку для команды, например php artisan help commandName.
migrate
Запускает все миграции базы данных.
optimize
Очищает и обновляет файлы конфигурации и маршрута.
serve
Привязывает PHP-сервер к адресу localhost:8000. Хост и/или порт можно настроить с помощью параметров --host и --port.
tinker
Запускает интерактивную оболочку Tinker REPL, о которой я расскажу позже в этой главе.
stub:publish
Публикует все заглушки, доступные для настройки.
docs
Дает быстрый доступ к документации Laravel. Если передать этой команде параметр, то она предложит открыть URL с запрошенным документом, в противном случае вы получите возможность перемещаться по списку тем в документации.
about
Выводит обобщенную информацию о среде проекта, конфигурации, пакетах и многом другом.
Изменения в списке команд Artisan с течением времени
Список команд Artisan и их имена в процессе развития Laravel понемногу менялись. Этот список был актуален на момент публикации книги. Однако лучший способ узнать, что вам доступно, — запустить php artisan из вашего приложения.
Параметры
Рассмотрим несколько важных параметров, которые можно передавать любым командам Artisan.
-q
Подавляет весь вывод.
-v, -vv и –vvv
Позволяет установить уровень детализации вывода (нормальный, подробный и отладочный).
--no-interaction
Подавляет интерактивные вопросы, поэтому команда не будет прерывать автоматизированные процессы, выполняющие ее.
--env
Позволяет задать, в какой среде должна работать команда Artisan (локальная, производственная и т. д.).
--version
Показывает, на какой версии Laravel работает ваше приложение.
Команды Artisan во многом подобны базовым командам оболочки: вы можете запускать их вручную, но они также могут функционировать как часть некоторого автоматизированного процесса.
Например, команды Artisan могут пригодиться в сценариях автоматического развертывания. Возможно, вы захотите запускать php artisan config:cache каждый раз, когда развертываете приложение. Флаги наподобие -q и --no-interaction обеспечивают бесперебойную работу сценариев развертывания без участия человека.
Сгруппированные команды
Остальные команды, доступные сразу же «из коробки», сгруппированы по контексту. Мы не будем рассматривать их все, но я расскажу о каждом контексте в общих чертах.
auth
В этом контексте имеется только команда auth:clear-resets, которая обновляет все токены сброса пароля с истекшим сроком действия в базе данных.
cache
cache:clear очищает кэш, cache:forget удаляет отдельный элемент из кэша, а cache:table создает миграцию базы данных, если вы планируете использовать драйвер кэша database.
config
config:cache кэширует ваши настройки конфигурации для быстрого поиска. Чтобы очистить кэш, используйте config:clear.
db
db:seed заполняет вашу базу данных, если вы настроили наполнители БД.
event
event:list выводит список всех событий и прослушивателей в приложении, event:cache кэширует этот список, event:clear очищает кэш, а event:generate создает недостающие файлы событий и слушателей на основе определений в EventServiceProvider. Вы узнаете больше о событиях в главе 16.
key
key:generate создает случайный ключ шифрования для приложения в вашем файле .env.
Повторный запуск artisan key:generate приводит к потере некоторых зашифрованных данных
Если запустить php artisan key:generate в приложении больше одного раза, то все авторизованные к данному моменту пользователи будут выброшены из системы. Кроме того, любые зашифрованные вручную данные больше не будут расшифровываться. Чтобы узнать больше, ознакомьтесь со статьей APP_KEY and You моего коллеги из Tightenite Джейка Бэтмена по адресу oreil.ly/T_l1h.
make
Каждое действие make: создает отдельный элемент и принимает соответствующие параметры. Чтобы узнать больше о параметрах любой отдельной команды, используйте help для получения соответствующей справки о команде.
Запустив php artisan help make:migration, вы узнаете, что можно передать параметр --create=tableNameHere и создать миграцию с кодом создания таблицы, например, так: php artisan make:migration create_posts_table --create=posts.
migrate
Об этой команде для запуска всех миграций уже рассказывалось ранее; подробные сведения обо всех командах, связанных с миграцией, смотрите в подразделе «Запуск миграций» в главе 5.
notifications
notifications:table генерирует миграцию, которая создает таблицу для уведомлений базы данных.
package
В Laravel есть манифест, созданный функцией автоматического обнаружения. В нем регистрируются сторонние пакеты при их первой установке. package:discover перестраивает обнаруженный манифест сервис-провайдеров Laravel из ваших внешних пакетов.
queue
Мы поговорим об очередях Laravel в главе 16, но основная идея в том, что вы можете помещать задания работнику в удаленные очереди для выполнения по порядку. Эта группа команд предоставляет инструменты взаимодействия с очередями, такие как queue:listen для начала прослушивания очереди, queue:table для создания миграции для очередей, поддерживаемых базой данных, и queue:flush для сброса всех неудачных заданий очереди. Об этом и многом другом вы узнаете в главе 16.
route
Если вы запустите route:list, то увидите определения всех маршрутов в приложении, включая команду/команды каждого маршрута, путь, имя, действие контроллера/замыкания и промежуточное ПО. Вы можете кэшировать определения маршрутов для быстрого поиска с помощью route:cache и очищать кэш с помощью route:clear.
schedule
Мы расскажем о cron-подобном планировщике Laravel в главе 16, но для его работы необходимо настроить запуск schedule:run раз в минуту в системном планировщике cron:
* * * * * php /home/myapp.com/artisan schedule:run >> /dev/null 2>&1
Эта команда Artisan предназначена для регулярного запуска и поддержки основного сервиса Laravel.
session
session:table создает миграцию для приложений, использующих сессии, которые хранятся в базе данных.
storage
storage:link создает символическую ссылку из public/storage в storage/app/public. Это общее соглашение в приложениях Laravel, позволяющее размещать выгружаемые пользователями данные (или другие файлы, которые обычно попадают в storage/app) там, где они будут достижимы по публичному URL-адресу.
vendor
Некоторые специфичные для Laravel пакеты должны «публиковать» кое-какие из своих ресурсов, чтобы они могли обслуживаться из вашего каталога public или чтобы вы могли изменять их. В любом случае данные пакеты регистрируют эти «публичные ресурсы» в Laravel. Когда вы запускаете команду vendor:publish, она публикует их в специфичных для них местах.
view
Движок визуализации Laravel автоматически кэширует ваши представления. Обычно он хорошо справляется со своевременной очисткой кэша, но, если вы когда-нибудь заметите, что он застрял, запустите view:clear для очистки кэша.
Написание пользовательских команд Artisan
Теперь, рассмотрев команды Artisan, поставляемые с Laravel, поговорим о написании собственных команд.
Для этого есть команда Artisan. Команда php artisan make:command YourCommandName создаст новую команду Artisan в app/Console/Commands/{YourCommandName}.php.
В первом аргументе этой команде нужно передать имя класса команды, а при желании можно также передать параметр --command, чтобы определить имя команды, которое должно вводиться в терминале (например, appname:action). Попробуем:
php artisan make:command WelcomeNewUsers --command=email:newusers
В примере 8.1 показан результат.
Пример 8.1. Каркас команды Artisan по умолчанию
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class WelcomeNewUsers extends Command
{
/**
* Имя и сигнатура консольной команды
*
* @var string
*/
protected $signature = 'email:newusers';
/**
* Описание консольной команды
*
* @var string
*/
protected $description = 'Command description';
/**
* Реализация консольной команды
*/
public function handle(): void
{
//
}
}
Как видите, определить сигнатуру команды, текст справки, отображаемый в списках команд, и поведение команды при выполнении (handle()) совсем не сложно.
Пример команды
Мы еще не рассмотрели почту или Eloquent в этой главе (почта описана в главе 15, а Eloquent — в главе 5), но образец метода handle() в примере 8.2 должен читаться довольно четко.
Пример 8.2. Образец метода handle() для команды Artisan
...
class WelcomeNewUsers extends Command
{
public function handle(): void
{
User::signedUpThisWeek()->each(function ($user) {
Mail::to($user)->send(new WelcomeEmail);
});
}
Теперь каждый раз при запуске php artisan email:newusers эта команда будет находить всех подписавшихся на этой неделе пользователей и отправлять им приветственные письма.
Если вы предпочитаете внедрять свои почтовые и пользовательские зависимости вместо использования фасадов, можно указать их тип в конструкторе команды. И контейнер Laravel внедрит их при создании экземпляра команды.
Взгляните на пример 8.3 — так может выглядеть пример 8.2, но с внедрением зависимостей и переносом поведения в отдельный вспомогательный класс.
Пример 8.3. Та же команда, рефакторинг
...
class WelcomeNewUsers extends Command
{
public function __construct(UserMailer $userMailer)
{
parent::__construct();
$this->userMailer = $userMailer
}
public function handle()
{
$this->userMailer->welcomeNewUsers();
}
НЕ УСЛОЖНЯЙТЕ
Команды Artisan доступны из остальной части вашего кода, поэтому их можно использовать для инкапсуляции логики приложения.
Однако в документации по Laravel рекомендуется упаковывать логику приложения в отдельный класс и внедрять его в вашу команду. Консольные команды похожи на контроллеры: они не являются предметными классами; они регулировщики, которые лишь правильно направляют поступающие запросы.
Аргументы и параметры
Свойство $signature новой команды выглядит так, будто оно может содержать только имя команды. Однако в действительности в нем также определяются аргументы и опции для команды. Существует специальный простой синтаксис, который можно использовать для добавления аргументов и параметров в ваши команды Artisan.
Прежде чем мы углубимся в этот синтаксис, взглянем на пример для некоторого контекста:
protected $signature = 'password:reset {userId} {--sendEmail}';
Аргументы: обязательные, необязательные и/или со значениями по умолчанию
Чтобы определить обязательный аргумент, поместите его в фигурные скобки:
password:reset {userId}
Для необязательного аргумента добавьте знак вопроса:
password:reset {userId?}
Чтобы сделать аргумент необязательным и задать значение по умолчанию, используйте следующую конструкцию:
password:reset {userId=1}
Опции: обязательные значения, значения по умолчанию и сокращенные формы
Опции похожи на аргументы, но имеют префикс — и могут использоваться без значения. Чтобы добавить простую опцию, заключите ее в фигурные скобки:
password:reset {userId} {--sendEmail}
Если опция требует значение — добавьте = к ее сигнатуре:
password:reset {userId} {--password=}
Если вы хотите передать значение по умолчанию, добавьте его после =:
password:reset {userId} {--queue=default}
Аргументы-массивы и опции-массивы
Чтобы позволить передавать массивы в аргументах и опциях, используйте символ *:
password:reset {userIds*}
password:reset {--ids=*}
В примере 8.4 показано, как передать массив в виде аргумента и опции.
Пример 8.4. Использование синтаксиса массива с командами Artisan
// Аргумент
php artisan password:reset 1 2 3
// Параметр
php artisan password:reset --ids=1 --ids=2 --ids=3
Аргумент-массив должен быть последним аргументом
Поскольку аргумент-массив захватывает все параметры после его определения и объединяет их в массив, такой аргумент должен быть последним в сигнатуре команды Artisan.
Описание ввода
Встроенные команды Artisan могут сообщать дополнительную информацию о своих параметрах, если использовать artisan help. Мы в своих командах тоже можем предоставить подобную информацию. Просто добавьте двоеточие и текст описания в фигурных скобках, как в примере 8.5.
Пример 8.5. Описание аргументов и опций Artisan
protected $signature = 'password:reset
{userId : The ID of the user}
{--sendEmail : Whether to send user an email}';
Использование ввода
Теперь, предусмотрев прием входных данных, мы должны как-то получить их в методе handle() нашей команды. Для этой цели существует два набора методов.
Методы argument() и arguments()
$this->arguments() возвращает массив всех аргументов (первым элементом будет имя команды). $this->argument() при вызове без параметров вернет тот же ответ. Я предпочитаю метод с именем во множественном числе, который лучше читается в коде.
Чтобы получить значение только одного аргумента, передайте имя аргумента в качестве параметра в $this->argument(), как показано в примере 8.6.
Пример 8.6. Использование $this->arguments() в команде Artisan
// С определением "password:reset {userId}"
php artisan password:reset 5
// $this->arguments() возвращает этот массив
[
"command": "password:reset",
"userId": "5",
]
// $this->argument('userId') возвращает эту строку
"5"
Методы option() и options()
$this->options() возвращает массив всех опций, включая те, что по умолчанию имеют значение false или null. $this->option() при вызове без параметров вернет тот же ответ. Я предпочитаю метод с именем во множественном числе, который лучше читается в коде.
Чтобы получить значение только одной опции, передайте ее имя в качестве параметра в $this->option(), как показано в примере 8.7.
Пример 8.7. Использование $this->options() в команде Artisan
// С определением "password:reset {--userId=}"
php artisan password:reset --userId=5
// $this->options() возвращает этот массив
[
"userId" => "5",
"help" => false,
"quiet" => false,
"verbose" => false,
"version" => false,
"ansi" => false,
"no-ansi" => false,
"no-interaction" => false,
"env" => null,
]
// $this->option('userId') возвращает эту строку
"5"
В примере 8.8 показана команда Artisan, использующая argument() и option() в методе handle().
Пример 8.8. Получение ввода в команде Artisan
public function handle()
{
// Все аргументы, включая имя команды
$arguments = $this->arguments();
// Только аргумент 'userId'
$userid = $this->argument('userId');
// Все опции, включая некоторые по умолчанию вроде 'no-interaction' и 'env'
$options = $this->options();
// Только опция 'sendEmail'
$sendEmail = $this->option('sendEmail');
}
Приглашения
Есть еще несколько способов получить пользовательский ввод внутри handle(), и все они предполагают интерактивный ввод информации пользователем во время выполнения вашей команды:
ask()
Предлагает пользователю ввести произвольный текст:
$email = $this->ask('What is your email address?');
secret()
Предлагает пользователю ввести произвольный текст, но скрывает ввод с помощью звездочек:
$password = $this->secret('What is the DB password?');
confirm()
Запрашивает у пользователя ответ «да/нет» и возвращает логическое значение:
if ($this->confirm('Do you want to truncate the tables?')) {
//
}
Все ответы, кроме y или Y, будут рассматриваться как «нет».
anticipate()
Предлагает пользователю ввести произвольный текст и предоставляет варианты автозаполнения, но позволяет пользователю ввести все, что он захочет:
$album = $this->anticipate('What is the best album ever?', [
"The Joshua Tree", "Pet Sounds", "What's Going On"
]);
choice()
Предлагает пользователю выбрать один из возможных вариантов. Последний параметр является значением по умолчанию, которое возвращается, если пользователь не сделал выбор:
$winner = $this->choice(
'Who is the best football team?',
['Gators', 'Wolverines'],
0
);
Последний параметр по умолчанию должен быть ключом массива. Поскольку мы передали неассоциативный массив, элементу Gators назначается ключ 0. При желании можно передать ассоциативный массив с ключами:
$winner = $this->choice(
'Who is the best football team?',
['gators' => 'Gators', 'wolverines' => 'Wolverines'],
'gators'
);
Вывод
Во время выполнения команды могут выводить сообщения пользователю. Например, вызов $this->info() выведет простой текст зеленого цвета:
$this->info('Your command has run successfully.');
Также доступны методы comment() (оранжевый), question() (жирный сине-зеленый), error() (жирный красный) и line() (черно-белый) и newLine() (черно-белый).
Обратите внимание, что точные цвета могут варьироваться от машины к машине, но все пытаются соответствовать стандартам для связи с конечным пользователем.
Табличный вывод
Метод table() упрощает создание таблиц ASCII, заполненных вашими данными. Посмотрите на пример 8.9.
Пример 8.9. Вывод таблиц в командах Artisan
$headers = ['Name', 'Email'];
$data = [
['Dhriti', 'dhriti@amrit.com'],
['Moses', 'moses@gutierez.com'],
];
// Данные можно получить из базы данных:
$data = App\User::all(['name', 'email'])->toArray();
$this->table($headers, $data);
В примере 8.9 есть два набора данных: заголовки и сами данные. Оба содержат две ячейки на строку. Первая ячейка в каждой строке — это имя, а вторая — адрес электронной почты. Таким образом, данные из вызова Eloquent (который ограничивается извлечением только имени и адреса электронной почты) совпадают с заголовками.
В примере 8.10 показан вывод таблицы.
Пример 8.10. Пример вывода таблицы Artisan
Индикаторы выполнения
Если вы когда-либо запускали npm install, то видели индикатор выполнения. Создадим один в примере 8.11.
Пример 8.11. Индикатор выполнения Artisan
$totalUnits = 350;
$this->output->progressStart($totalUnits);
for ($i = 0; $i < $totalUnits; $i++) {
sleep(1);
$this->output->progressAdvance();
}
$this->output->progressFinish();
Сначала мы сообщили системе, сколько единиц нам нужно обработать. Может быть, единица — это пользователь, а у вас 350 пользователей. Затем индикатор разделит всю ширину, доступную на вашем экране, на 350 и будет закрашивать 1/350 часть при каждом вызове progressAdvance(). Когда вы закончите, вызовите progressFinish(), чтобы индикатор знал, что должен прекратить отображаться.
Команды на основе замыканий
Для простоты команды можно определять не как классы, а как замыкания в routes/console.php. Все, о чем рассказывается в текущей главе, в равной степени применимо и к данному способу, с той лишь разницей, что команды определяются и регистрируются в этом файле за один шаг, как показано в примере 8.12.
Пример 8.12. Определение команды Artisan с использованием замыкания
// routes/console.php
Artisan::command(
'password:reset {userId} {--sendEmail}',
function ($userId, $sendEmail) {
$userId = $this->argument('userId');
// Некий код...
}
);
Вызов команд Artisan в нормальном коде
Команды Artisan предназначены для запуска из командной строки, но их также можно вызывать из другого кода.
Самый простой способ — использовать фасад Artisan. Вызвать команду можно с помощью функции Artisan::call() (которая вернет код завершения команды), или поставить команду в очередь, использовав Artisan::queue().
Обе функции принимают два параметра: консольную команду (password:reset) и массив параметров для нее. В примере 8.13 показана работа с аргументами и опциями.
Пример 8.13. Вызов команд Artisan из другого кода
Route::get('test-artisan', function () {
$exitCode = Artisan::call('password:reset', [
'userId' => 15,
'--sendEmail' => true,
]);
});
Значения аргументов передаются вместе с их именами, а с опциями без значения можно передавать true или false.
Есть более простой способ вызова команд Artisan из кода. Передайте ту же строку, которую вы вводите в командной строке, в вызов Artisan::call():
Artisan::call('password:reset 15 --sendEmail')
Команды Artisan можно вызывать из других команд, используя $this->call() (действует так же, как Artisan::call()) или $this->callSilent() (действует аналогично, но подавляет вывод). Посмотрите на пример 8.14.
Пример 8.14. Вызов команд Artisan из других команд Artisan
public function handle()
{
$this->callSilent('password:reset', [
'userId' => 15,
]);
}
Наконец, можно внедрить экземпляр контракта Illuminate\Contracts\Console\Kernel и использовать его метод call().
Tinker
Tinker — это интерактивная оболочка REPL, или «прочитать — выполнить — вывести результат — повторить». REPL выводит приглашение, похожее на приглашение командной строки, которое имитирует состояние ожидания вашего приложения. Вы вводите свои команды в REPL, нажимаете Return и ожидаете, пока команда выполнится и на экране появится ответ.
В примере 8.15 приводится короткая выдержка из сеанса работы с оболочкой REPL, чтобы вы могли получить представление о том, как она работает и насколько может быть полезной. После входа в REPL командой php artisan tinker мы получаем приглашение (>>>). Каждый ответ на наши команды выводится в строке, начинающейся с символов =>.
Пример 8.15. Использование Tinker
$ php artisan tinker
>>> $user = new App\User;
=> App\User: {}
>>> $user->email = ‘matt@mattstauffer.com’;
=> "matt@mattstauffer.com"
>>> $user->password = bcrypt(‘superSecret’);
=> "$2y$10$TWPGBC7e8d1bvJ1q5kv.VDUGfYDnE9gANl4mleuB3htIY2dxcQfQ5"
>>> $user->save();
=> true
Мы создали нового пользователя, установили некоторые данные (для безопасности хешировали пароль с помощью bcrypt()) и сохранили их в базе данных. И это реально. Будь это производственное приложение, мы бы просто создали нового пользователя в системе.
Это делает Tinker отличным инструментом для выполнения простых операций с базой данных, апробации новых идей и запуска фрагментов кода, когда трудно найти место для размещения их в исходных файлах приложения.
Tinker работает на Psy Shell (http://psysh.org/). Загляните по этому адресу, чтобы узнать, что еще может предложить Tinker.
Сервер дампа Laravel
Одним из распространенных методов отладки состояния данных во время разработки является использование вспомогательной функции dump() Laravel, которая запускает более красивый var_dump() для всего, что вы ей передаете. Это хорошо, но часто чревато проблемами с представлениями.
В проектах Laravel можно включить сервер дампа Laravel, который будет перехватывать обращения к dump() и отображать вывод в консоли вместо страницы.
Чтобы запустить сервер дампа в локальной консоли, перейдите в корневой каталог проекта и запустите php artisan dump-server:
$ php artisan dump-server
Laravel Var Dump Server
=======================
[OK] Server listening on tcp://127.0.0.1:9912
// Остановить сервер можно нажатием CTRL+C
Теперь попробуйте использовать функцию dump() где-нибудь в вашем коде. Для пробы введите этот код в ваш файл route/web.php:
Route::get('/', function () {
dump('Dumped Value');
return 'Hello World';
});
Без сервера дампов вы увидите в браузере и дамп, и строку «Hello, World!». Но после запуска сервера дампов в браузере появится только строка «Hello, World!». В своей консоли вы увидите, что сервер дампа перехватил вызов dump(), и вы можете исследовать вывод там:
GET http://myapp.test/
--------------------
------------ ---------------------------------
date Tue, 18 Sep 2018 22:43:10 +0000
controller "Closure"
source web.php on line 20
file routes/web.php
------------ ---------------------------------
"Dumped Value"
Настройка шаблонов генератора
Любые команды Artisan, генерирующие файлы (например, make:model и make:controller), используют файлы-шаблоны, которые команда затем копирует и изменяет, чтобы создать новые файлы. Вы можете настроить эти шаблоны в своих приложениях.
Для этого запустите команду php artisan stub:publish — она опубликует файлы шаблонов в каталог stub/, где вы сможете их настроить.
Тестирование
Зная, как вызывать команды Artisan из кода, вы с легкостью сможете добавить их в свои тесты и проверить правильность любого ожидаемого поведения, как показано в примере 8.16. В наших тестах мы используем метод $this->artisan() вместо Artisan::call(), потому что он имеет тот же синтаксис, но добавляет несколько связанных с тестированием проверок.
Пример 8.16. Вызов команд Artisan из теста
public function test_empty_log_command_empties_logs_table()
{
DB::table('logs')->insert(['message' => 'Did something']);
$this->assertCount(1, DB::table('logs')->get());
$this->artisan('logs:empty'); // То же, что и Artisan::call('logs:empty');
$this->assertCount(0, DB::table('logs')->get());
}
При желании вы можете добавить цепочку проверок к вызову $this->artisan(). Это поможет упростить тестирование команд Artisan и понять не только какое влияние они оказывают на остальную часть вашего приложения, но и как они на самом деле работают. В примере 8.17 приведен образец такого синтаксиса.
Пример 8.17. Проверка ввода и вывода команд Artisan
public function testItCreatesANewUser()
{
$this->artisan('myapp:create-user')
->expectsQuestion("What's the name of the new user?", "Wilbur Powery")
->expectsQuestion("What's the email of the new user?", "wilbur@thisbook.co")
->expectsQuestion("What's the password of the new user?", "secret")
->expectsOutput("User Wilbur Powery created!");
$this->assertDatabaseHas('users', [
'email' => 'wilbur@thisbook.co'
]);
}
Резюме
Команды Artisan являются инструментами командной строки Laravel. Laravel поставляется с несколькими готовыми командами Artisan, но их легко создавать и вызывать из командной строки или собственного кода.
Tinker — это интерактивная оболочка REPL, которая упрощает вход в среду вашего приложения и взаимодействие с реальными кодом и данными, а сервер дампа позволяет отлаживать код без остановки его выполнения.
Об авторе
Мэтт Стауффер — программист, автор книг и статей, участник конференций, подкастер, видеоблогер и просто хороший парень. Он совладелец и технический директор компании Tighten, ведет блог на сайте mattstauffer.com и администрирует подкаст по фреймворку Laravel.
Более подробно с книгой можно ознакомиться на сайте издательства:
» Оглавление
» Отрывок
По факту оплаты бумажной версии книги на e-mail высылается электронная книга.
Для Хаброжителей скидка 25% по купону — Laravel