+7

Artisan Console trong Laravel

Xin chào tất cả mọi người, gần đây mình có làm một số task liên quan đến việc cập nhật cũng như convert dữ liệu trên database, và mình tìm hiểu được Laravel có một công cụ hỗ trợ rất tốt cho việc này đó là Artisan console và mình xin trình bày về một chút kiến thức mà mình tìm hiểu được về nó.

1) Artisan Console là gì?

  • Artisan là giao diện command-line đính kèm theo Laravel. Artisan cung cấp cho chúng ta một danh sách các câu lệnh hữu ích để sử dụng trong quá trình làm dự án. Artisan được phát triển dựa trên component Symfony Console.
  • Để xem danh sách các câu lệnh được hỗ trợ, bạn có thể sử dụng câu lệnh sau:

php artisan list

2) Lợi ích khi sự dụng Artisan Console

  • Xử lý các công việc mang tính thủ công bằng cách tự động hóa chúng
  • Chạy các công việc ngầm theo kiểu hàng đợi
  • Artisan cũng có thể tạo các template là các Class trong lập trình theo các mẫu khác nhau như tạo ra các Model, Controller, Event…

3) Tạo Artisan Console cho mục đích riêng

  • Ngoài việc sử dụng các câu lệnh được cung cấp sẵn, ban cũng có thể tạo câu lệnh riêng để sử dụng cho ứng dụng của bạn. Bạn có thể lưu trữ các câu lệnh riêng đó trong thư mục app/Console/Commands.
  • Để tạo một command, chúng ta sử dụng câu sau:

php artisan make:command ConvertEmails

  • Nó sẽ tạo ra các khung mã nguồn cơ bản để giúp chúng ta bắt đầu một cách dễ dàng hơn:
  • Câu lệnh trên sẽ tạo một class tại app/Console/Commands/ConvertEmails.php.
  • Khi đó bạn sẽ thấy file ConvertEmails.php nằm trong app\Console\Commands với nội dung mẫu như sau:
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

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

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
    }
}

  • Lớp này là được kế thừa lớp Command và có hai thuộc tính quan trọng là $signature và $description.
  • Thuộc tính signature cho phép bạn khai báo tên, đối số, và các tuỳ chọn cho câu lệnh dưới dạng một giá trị, một biểu thức.
  • Thuộc tính description là phần để chúng ta viết mô tả xem Artisan của chúng ta có nhiệm vụ gì
  • Phương thức handle() sẽ được gọi đến khi thực hiện câu lệnh Artisan.

3.1) Định nghĩa các tham số và tùy chọn cho câu lệnh Artisan

  • Các tham số cho câu lệnh Artisan được định nghĩa trong thuộc tính $signature. Thuộc tính này cho phép ta định nghĩa tên câu lệnh, tham số và các tùy chọn.
  • Các tham số được định nghĩa trong hai dấu ngoặc nhọn {parameter}. Chúng ta cũng có thể mặc định giá trị ban đầu cho các tham số như sau:
protected $signature = 'user:convert-email {limit}';
  • Cả tham số và tùy chọn ở trên đều có thể đưa vào câu lệnh dưới dạng mảng, khi đó chúng ta sử dụng ký tự * để hàm ý các đầu vào là dạng mảng:
protected $signature = 'user:convert-email {user*}';
  • Với thuộc tính signature chúng ta cũng có thể đưa vào các text mô tả cho từng tham số hoặc tùy chọn băng cách như sau:
 protected $signature = 'user:create 
                           {limit : lấy ra bao nhiêu bản ghi} 
                           {user* : Giá trị id của các user}';

3.2) Thao tác dữ liệu vào ra của câu lệnh Artisan

  • Trong phần trên chúng ta đã được giới thiệu cách định nghĩa các tham số và tùy chọn, vậy thao tác với các dữ liệu này như thế nào, lớp Command có các phương thức argument() và option() để lấy các giá trị nhập vào:
public function handle()
    {
        // Lấy tham số limit
        $userType = $this->argument('limit');
        // Lấy tất cả các tham số
        $arguments = $this->arguments();
        // Lấy tất cả các tham số
        $arguments = $this->option();
    }

3.3) Hỏi yêu cầu nhập dữ liệu

  • Ngoài việc hiển thị, chúng ta cũng có thể yêu cầu người dùng nhập dữ liệu trong quá trình thực thi câu lệnh
  • Phương thức ask() sẽ yêu cầu người dùng nhập dữ liệu với câu hỏi được đưa ra
public function handle()
{
    $name = $this->ask('What is your name?');
}
  • Phương thức secret() tương tự như ask() nhưng dữ liệu mà người dùng nhập khi gõ bàn phím sẽ không được hiển thị lên. Phương thức này rất hữu ích khi yêu cầu các thông tin nhạy cảm như mật khẩu
public function handle()
{
    $password = $this->secret('What is the password?');
}
  • confirm(): câu hỏi xác nhận, mặc định phương thức trả về false, tuy nhiên như người dùng nhập vào y hoặc yes thì nó sẽ trả về giá trị true
public function handle()
{
    if ($this->confirm('Do you wish to continue?')) {
        //
    }
}
  • anticipate(): cho phép auto-completion với các tùy chọn có thể
public function handle()
{
    $name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);
}
  • choice(): Câu hỏi nhiều lựa chọn, các lựa chọn được định nghĩa trước.
public function handle()
{
    $name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $default);
}

3.4) Hiển thị thông tin khi thực hiện câu lệnh artisan

  • Để hiển thị nội dung ra màn hình, sử dụng các phương thức sau line, info, comment, question và error. Mỗi phương thức sẽ sử dụng màu ANSI tương ứng với mục đích của nó
  • Để hiển thị thông tin cho người dùng, sử dụng info(). Về cơ bản, nó sẽ hiển thị chữ màu xanh lá cây
  • Để hiển thị nội dung về lỗi, sử dụng error(). Nội dung lỗi sẽ được hiển thị màu đỏ.
  • Nếu bạn muốn hiển thị nội dung đơn thuẩn, sử dụng line()-phương thức này không sử dụng bất cứ màu đặc trưng nào
public function handle()
{
    try {
        $this->info('Convert email success');
    } catch (e Exception) {
        $this->error('Convert email fail');
    }
}

-Hiển thị thanh tiến trình là rất cần thiết với các công việc thực hiện mất nhiều thời gian, một câu lệnh mất đến 5 phút mà không hiển thị gì lên màn hình thì đúng là ác mộng, với thanh tiến trình chúng ta có thể biết được công việc đã thực hiện được bao nhiêu phần trăm

$users = App\User::all();

$bar = $this->output->createProgressBar(count($users));

foreach ($users as $user) {
    $this->performTask($user);

    $bar->advance();
}

$bar->finish();

3.5) Đăng ký command với hệ thống

  • Khi mà đã hoàn thành các lệnh ở trên,chúng ta cần phải đăng kí với Artisan để câu lệnh có thể sử dụng được. Chúng ta truy cập vào file app/Console/Kernel.php của project:
  • Trong file này, chúng ta có thể thấy thuộc tính commands nơi mà chúng ta đăng ký command là ở đây, tất cả các câu lệnh trong danh sách này sẽ được duyệt bởi service container và sẽ được đăng kí vào Artisan:
protected $commands = [
        Commands\ConvertEmails::class
    ];
  • Sau khi đăng ký xong, chúng ta sẽ thấy thông tin câu lệnh command user:convert-email trong php artisan list, Sau đó chúng ta có thể thực hiện được lệnh php artisan user:convert-email như các lệnh artisan sẵn có.

4) Ví dụ

  • Ở trên mình là phần lý thuyết giờ chúng ta đi vào làm một ví dụ nhỏ. Trong ví dụ này mình sẽ viết một Artisan để convert địa chỉ email có đuôi là "@framgia.com" sang "@sun-asterisk" (Vì công ty chuyển thương hiệu mới nên yêu cầu email của các tài khoản dự án mình đang làm cũng phải chuyển đổi theo) 😃
  • Đầu tiên chúng ta chạy lệnh:
php artisan make:command ConvertEmails
  • Tiếp theo là xử lý các logic:
<?php

namespace App\Console\Commands;

use Exception;
use App\User;
use Illuminate\Console\Command;

class ConvertEmails extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'user:convert-email';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Convert email in table users';

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $users = User::where('email', 'like', '%@framgia.com%')->get();
        $users->each(function ($user) {
            $this->convertEmail($user);
        });
    }

    protected function convertEmail(User $user)
    {
        try {
            $oldEmail = $user->email;
            $newEmail = str_replace('@framgia.com', '@sun-asterisk.com', $user->email);
            $user->email = $newEmail;
            $user->save();
            $this->info("convert email from {$oldEmail} to {$newEmail} Success!");
        } catch (Exception $e) {
            $this->error("convert email {$oldEmail} Fail!");
            $this->error('--- ' . $e->getMessage());
        }
    }
}

  • Tiếp theo, để sử dụng được câu lệnh này chúng ta cần đăng ký nó trong app\Console\Kernel.php trong thuộc tính $commands:
<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        Commands\ConvertEmails::class
    ];
    ....
}

  • Đây là dữ liệu trên database trước khi chạy lệnh php artisan user:convert-email:

  • Sau khi chạy lệnh php artisan user:convert-email ta thu được kết quả sau:

  • 😮 thật là nhanh gọn! 😄

Kết luận

  • Trên đây là một chút kiến thức mình tìm hiểu được về Artisan mong có thế giúp ích được cho các bạn! Cám ơn tất cả mọi người dã theo dõi bài viết của mình

Nguồn tham khảo


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.