Laravel – это открытый PHP-фреймворк, в котором вы найдете набор инструментов и ресурсов для создания современных PHP-приложений. Эта серия руководств поможет вам создать простое приложение на платформе Laravel, используя среду разработки PHP, контейнеризованную при помощи Docker Compose. В итоге вы получите одностраничный веб-сайт, которым можно управлять с помощью команд Artisan. На этом сайте вы сможете делиться с аудиторией актуальными ссылками.
Примечание: Другие части этой серии можно найти по этой ссылке.
Если вы выполнили предыдущие руководства этой серии, у вас уже есть готовые таблицы БД. Теперь же нам необходимо разработать способ, позволяющий пользователям вставлять новые записи в таблицу links.
Чтобы наше тестовое приложение было полнофункциональным, мы напишем команды Artisan для создания и удаления ссылок в БД. Artisan – это инструмент командной строки, который поставляется с Laravel и предлагает ряд утилит для ускорения процесса разработки (включая утилиты для генерации шаблонного кода, удаления и восстановления базы данных приложения).
Использование командной строки для управления приложением может стать хорошей альтернативой веб-формам и защищенным областям, поскольку для работы с командной строкой пользователь должен быть зарегистрирован на сервере, а не пройти аутентификацию в браузере. Если позже вы решите использовать защищенную область, вы сможете создать веб-формы, которые позволят зарегистрированным пользователям отправлять новые ссылки в базы данных.
Команды Artisan часто используются для того, чтобы вручную или автоматически (через механизм планирования типа Crontab) запускать задачи приложения, которые должны выполняться в фоновом режиме. Их также можно использовать для быстрого создания прототипов новых функций приложения, которые необходимо динамически настраивать в зависимости от ввода авторизованного пользователя.
Для начала создадим новую команду Artisan; для этого есть вспомогательная команда make:command:
docker-compose exec app php artisan make:command LinkNew
Console command created successfully.
Она создаст файл LinkNew.php в каталоге app/Console/Commands. Внутри этого класса (который является расширением родительского класса Illuminate\Console\Command) нам нужно будет реализовать метод handle, который будет выполняться при вызове этой команды. Чтобы определить подпись команды, установите значение link:new для защищенного свойства $signature.
Откройте новый файл в текстовом редакторе или редакторе кода:
nano app/Console/Commands/LinkNew.php
Чтобы вы могли сохранить новую ссылку в базу данных, в метод handle должны произойти несколько вещей. Во-первых, нужно запросить у пользователей входные данные, чтобы получить URL-адрес.
$url = $this->ask('Link URL:');
Затем на понадобится функция filter_var, которая подтвердит, что ввод, полученный от пользователя, является допустимым URL-адресом. Если ссылка недействительна, пользователь увидит сообщение об ошибке и выйдет из приложения с кодом состояния 1 (который значит, что приложение завершило работу из-за ошибки).
if (!filter_var($url, FILTER_VALIDATE_URL)) {
$this->error("Invalid URL. Exiting...");
return 1;
}
Если ссылка действительна, приложение продолжит работу и запросит описание ссылки (тем же способом, что и раньше).
$description = $this->ask('Link Description:');
Затем приложение запросит окончательное подтверждение того, что все данные верны, для этого существует вспомогательная команда confirm. Если пользователь подтверждает данные, ссылка будет вставлена в БД. Для взаимодействия с базой данных мы используем модель Eloquent по имени Link, созданную в предыдущей части этой серии.
$this->info("New Link:");
$this->info($url . ' - ' . $description);
if ($this->confirm('Is this information correct?')) {
$link = new Link();
$link->url = $url;
$link->description = $description;
$link->save();
$this->info("Saved.");
}
Приложение завершит работу с кодом 0 – это успешный статус (то есть 0 ошибок).
return 0;
Следующий код включает все эти изменения. Замените текущий код в вашем классе app/Console/Commands/LinkNew.php на такой:
<?php
namespace App\Console\Commands;
use App\Models\Link;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class LinkNew extends Command
{
/**
* имя и подпись консольной команды.
*
* @var string
*/
protected $signature = 'link:new';
/**
* описание команды.
*
* @var string
*/
protected $description = 'Create a New Link';
/**
* создание нового экземпляра команды.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* выполнение команды.
*
* @return int
*/
public function handle()
{
$url = $this->ask('Link URL:');
if (!filter_var($url, FILTER_VALIDATE_URL)) {
$this->error("Invalid URL. Exiting...");
return 1;
}
$description = $this->ask('Link Description:');
$this->info("New Link:");
$this->info($url . ' - ' . $description);
if ($this->confirm('Is this information correct?')) {
$link = new Link();
$link->url = $url;
$link->description = $description;
$link->save();
$this->info("Saved.");
}
return 0;
}
}
Сохраните и закройте файл, когда закончите работу.
Чтобы выполнить команду и вставить новую ссылку в базу данных, запустите:
docker-compose exec app php artisan link:new
Вы получите такой вывод:
Link URL::
> https://www.8host.com/blog/
Link Description::
> Community
New Link:
https://www.8host.com/blog/ - Community
Is this information correct? (yes/no) [no]:
> yes
Saved.
Если хотите, можете добавить еще несколько ссылок.
Список ссылок
А теперь нужно создать новую команду Artisan для отображения списка всех ссылок. Назовем эту команду link:list.
Создайте новую команду с помощью:
docker-compose exec app php artisan make:command LinkList
Откройте класс handle, используя любой текстовый редактор или редактор кода:
nano app/Console/Commands/LinkList.php
В методе handle этой команды мы запросим все строки таблицы links. Вы можете использовать модель Link для доступа к базовым методам запросов к базе данных, которые предоставляет Eloquent. Чтобы красиво отобразить результаты в командной строке, мы обратимся к вспомогательной команде вывода table:
$headers = [ 'id', 'url', 'description' ];
$links = Link::all(['id', 'url', 'description'])->toArray();
$this->table($headers, $links);
return 0;
Ниже вы найдете полную реализацию команды link:list. Замените содержимое файла app/Console/Commands/LinkList.php следующим:
<?php
namespace App\Console\Commands;
use App\Models\Link;
use Illuminate\Console\Command;
class LinkList extends Command
{
/**
* имя и подпись консольной команды.
*
* @var string
*/
protected $signature = 'link:list';
/**
* описание команды.
*
* @var string
*/
protected $description = 'List links saved in the database';
/**
* создание нового экземпляра команды.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Выполнение команды.
*
* @return int
*/
public function handle()
{
$headers = [ 'id', 'url', 'description' ];
$links = Link::all(['id', 'url', 'description'])->toArray();
$this->table($headers, $links);
return 0;
}
}
Сохраните и закройте файл, когда закончите.
Чтобы запустить эту команду и показать список всех ссылок, уже вставленных в таблицу links, выполните:
docker-compose exec app php artisan link:list
Вы получите такой вывод:
+—-+————————————+————–+
| id | url | description |
+—-+————————————+————–+
| 1 | https://www.8host.com/blog/ | Community |
| 2 | https://laravel.com | Laravel |
+—-+————————————+————–+
А сейчас мы создадим команду для удаления ссылок:
docker-compose exec app php artisan make:command LinkDelete
Вывод:
Console command created successfully.
Откройте новый файл с помощью выбранного текстового редактора или редактора кода:
nano app/Console/Commands/LinkDelete.php
Назовем эту команду link:delete. Чтобы узнать, какую ссылку необходимо удалить, приложение должно потребовать, чтобы пользователи указали дополнительный аргумент при вызове команды: идентификатор ссылки. Это также устанавливается в переменной $signature, которая определяет, как вызывается команда и какие аргументы (обязательные или опциональные) должны быть в ней:
protected $signature = 'link:delete {link_id}';
Метод handle этой команды реализует несколько разных инструкций. Сначала приложение получит идентификатор ссылки, который должен быть указан в вызове команды.
$link_id = $this->argument('link_id');
Затем указанная ссылка извлекается из базы данных с помощью метода поиска Eloquent, который доступен в вашей модели Link.
$link = Link::find($link_id);
Если метод find не находит в базе данных запись с таким идентификатором, он вернет null. Затем приложение проверит, является ли это текущим значением, содержащимся в переменной $link, и в этом случае вернет ошибку. Программа завершит работу с ошибкой (код 1).
if ($link === null) {
$this->error("Invalid or non-existent link ID.");
return 1;
}
Если значение $link не равно нулю, команда продолжает выполнение. Затем мы используем вспомогательную команду confirm, чтобы запросить подтверждение пользователя.
if ($this->confirm(‘Are you sure you want to delete this link? ‘ . $link->url)) {
// удаляет ссылку
}
Когда пользователь подтверждает действие, набрав yes и нажав Enter, приложение вызывает метод delete из модели Link, чтобы удалить указанную ссылку из базы данных.
$link->delete();
$this->info("Link deleted.");
Ниже вы найдете полный код команды list:delete. Замените содержимое файла LinkDelete.php этим кодом:
<?php
namespace App\Console\Commands;
use App\Models\Link;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class LinkDelete extends Command
{
/**
* имя и подпись консольной команды.
*
* @var string
*/
protected $signature = 'link:delete {link_id}';
/**
* описание команды.
*
* @var string
*/
protected $description = 'Deletes a link from the database.';
/**
* Создание нового экземпляра команды.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Выполнение команды.
*
* @return int
*/
public function handle()
{
$link_id = $this->argument('link_id');
$link = Link::find($link_id);
if ($link === null) {
$this->error("Invalid or non-existent link ID.");
return 1;
}
if ($this->confirm('Are you sure you want to delete this link? ' . $link->url)) {
$link->delete();
$this->info("Link deleted.");
}
return 0;
}
}
Сохраните и закройте файл, когда закончите.
Если теперь вы захотите удалить ссылку из таблицы links, вам сначала нужно будет получить идентификатор ссылки с помощью команды artisan link:list, как было показано ранее. Как только вы узнаете идентификатор, вы сможете запустить команду artisan link:delete с помощью:
docker-compose exec app php artisan link:delete LINK_ID
Вы получите такой вывод:
Are you sure you want to delete this link? https://laravel.com (yes/no) [no]:
> yes
Link deleted.
Теперь вы можете вставлять ссылки в БД приложения, а также запрашивать их список и удалять их с помощью команд Artisan, выполняемых из командной строки. В следующей части этой серии мы сосредоточимся на внешнем интерфейсе приложения и разработаем его с помощью шаблонов Blade и CSS-фреймворка Bulma.