如何在 Laravel 中创建 Artisan 命令来管理数据库记录


本系列的一部分:
如何使用 Laravel 和 Docker Compose 在 PHP 中构建链接登陆页面

Laravel是一个开源 PHP 框架,它提供了一组工具和资源来构建现代 PHP 应用程序。在这个基于项目的教程系列中,您将使用 Laravel 框架构建一个Links Landing Page应用程序,使用由 Docker Compose 管理的容器化 PHP 开发环境。

最后,您将拥有一个使用 Laravel 构建并通过 Artisan 命令管理的单页网站,您可以在其中将相关链接分享给社交渠道和演示文稿上的受众。

如果到目前为止您一直在学习本系列,那么您的数据库表应该已经全部设置好了。但是,您仍然需要实现一种方法来让用户在links表中插入新条目

为了限制本系列的范围,同时使应用程序功能齐全,您将设置 Artisan 命令来创建和删除数据库中的链接。Artisan 是 Laravel 附带的命令行工具,提供了许多实用程序来加速开发过程,从生成样板代码到删除和重新创建应用程序的数据库。

使用命令行界面来管理您的应用程序可以替代 Web 表单和安全区域,因为它需要用户登录到服务器才能执行此类命令,而不是通过浏览器进行身份验证。如果您稍后决定为您的应用程序创建一个安全区域,您可以创建 Web 表单以允许注册用户提交到数据库的新链接。

Artisan 命令通常用于执行应在后台运行的应用程序任务,手动或通过调度机制(如 Crontab)自动执行。它们还可用于促进需要动态配置的新应用程序功能的原型设计,具体取决于来自授权用户的输入。

首先,使用make:command帮助程序创建一个新的 Artisan 命令

  • docker-compose exec app php artisan make:command LinkNew
Output
Console command created successfully.

这将创建一个名为 的文件LinkNew.php,位于app/Console/Commands目录中。在这个继承自Illuminate\Console\Command父类的类中,您需要实现一个handle方法,方法将在调用此命令时执行。要定义命令的签名,您需要将$signatureprotected 属性设置link:new

使用您选择的文本或代码编辑器打开新文件。在这里,我们将使用nano

  • 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:');

然后,您将使用确认帮助程序要求最终确认所有数据是否正确如果用户确认,链接最终会插入到数据库中。您将使用在Link本系列的前一部分中创建Eloquent 模型与数据库进行交互。

        $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;

以下代码包含这些步骤的完整实现。LinkNew班级中的当前内容替换为

应用程序/控制台/命令/LinkNew.php
<?php

namespace App\Console\Commands;

use App\Models\Link;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class LinkNew extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'link:new';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Create a New Link';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @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
Output
Link URL:: > https://digitalocean.com/community Link Description:: > DigitalOcean Community New Link: https://digitalocean.com/community - DigitalOcean Community Is this information correct? (yes/no) [no]: > yes Saved.

如果您愿意,可以随意添加更多链接。

接下来,您需要创建一个新的 Artisan 命令来显示所有链接的列表。您可以调用它link:list使用以下命令创建新命令:

  • docker-compose exec app php artisan make:command LinkList

使用您选择的文本或代码编辑器打开命令类:

  • nano app/Console/Commands/LinkList.php

handle此命令方法中,您将查询links表中的所有行您可以使用该Link模型访问Eloquent 提供的底层数据库查询方法要在命令行中很好地展示结果,您可以使用输出助手:

        $headers = [ 'id', 'url', 'description' ];
        $links = Link::all(['id', 'url', 'description'])->toArray();
        $this->table($headers, $links);

        return 0;

以下代码包含该link:list命令的完整实现LinkList.php文件中的内容替换为

应用程序/控制台/命令/LinkList.php
<?php

namespace App\Console\Commands;

use App\Models\Link;
use Illuminate\Console\Command;

class LinkList extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'link:list';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'List links saved in the database';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @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
Output
+----+------------------------------------+--------------+ | id | url | description | +----+------------------------------------+--------------+ | 1 | https://digitalocean.com/community | DO Community | | 2 | https://laravel.com | Laravel | +----+------------------------------------+--------------+

最后,您将创建一个命令来删除链接:

  • docker-compose exec app php artisan make:command LinkDelete
Output
Console command created successfully.

使用您选择的文本或代码编辑器打开新文件:

  • nano app/Console/Commands/LinkDelete.php

您可以命名此命令link:delete要知道必须删除哪个链接,您需要要求用户在调用命令时提供额外的参数:链接的 ID。这也在$signature变量中设置,该变量定义了命令的调用方式以及应提供哪些参数(强制性或非强制性):

protected $signature = 'link:delete {link_id}';

handle此命令方法将实现一些不同的指令。首先,您将获得应该在命令调用中提供的链接 ID。

$link_id = $this->argument('link_id');

然后,您将使用模型中find可用的 Eloquent 方法从数据库中获取引用的链接Link

$link = Link::find($link_id);

当该find方法找不到具有该 ID 的数据库记录时,它将返回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)) {
    // deletes link
}

当用户通过键入yes并点击确认操作时ENTER,您将从Eloquent 模型调用该delete方法Link以从数据库中删除指定的链接。

            $link->delete();
            $this->info("Link deleted.");

以下代码包含该list:delete命令的完整实现LinkDelete.php文件中的内容替换为以下内容:

应用程序/控制台/命令/LinkDelete.php
<?php

namespace App\Console\Commands;

use App\Models\Link;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class LinkDelete extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'link:delete {link_id}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Deletes a link from the database.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @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;
    }
}

完成后保存并关闭文件。

现在,当您想要从链接表中删除链接时,您首先需要使用 获取链接的 ID artisan link:list,如前面所示。知道链接的 ID 后,您可以使用以下artisan link:delete命令运行命令:

  • docker-compose exec app php artisan link:delete LINK_ID
Output
Are you sure you want to delete this link? https://laravel.com (yes/no) [no]: > yes Link deleted.

您现在可以使用从命令行界面执行的 Artisan 命令在应用程序的数据库中插入、列出和删除链接。在本系列的下一部分中,您将使用 Blade 模板和 Bulma CSS 框架设置应用程序的前端。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁