image Привет, Хаброжители!

Что отличает 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, а затем — менее фундаментальные и реже используемые возможности.

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

Большинство глав заканчивается двумя разделами: «Тестирование» и «Резюме». В них соответственно показывается, как писать тесты для представленных возможностей, и проводится общий обзор рассмотренного материала.

В книге описывается работа с 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

image

Индикаторы выполнения


Если вы когда-либо запускали 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

Комментарии (0)