+1

Laravel Commands

Ngày nay, đối với một developer thì việc hiểu biết về consoles và làm thế nào để tạo ra được một commands đơn giản không còn là vấn đề quá xa lạ. Nhưng làm cách nào để có thể cải thiện những comamnds của bạn giúp công việc của bạn trở nên dễ dàng hơn? Trong Laravel 4 đã tích hợp sẵn một gói thư viện hữu ích là Artisan, nó sẽ khiến công việc lập trình của bạn trở nên nhẹ nhàng hơn rất nhiều.

Artisan là gì?

    Artisan là tiện ích dòng lệnh được sử dụng trong laravel 3

Nếu bạn đã từng sử dụng các framework khác, bạn có thể so sánh Artisan với Oil trong FuelPHP, ZFTool trong Zend, hay Console trong Symfony 2.

Artisan cung cấp nhiều lệnh hữu ích giúp bạn có thể thực hiện được nhiều lệnh khác nhau. Chẳng hạn như khi bạn tạo một file migrations hay cài đặt thêm một packages. Ngoài các lệnh cài đặt, chúng ta cũng có thể mở rộng Artisan với chính commands của mình.

Nền tảng của Artisan

Trong Laravel 3, Artisan được viết hoàn toàn bởi Taylor Otwel, vì vậy nó khá cơ bản. Bây giờ Laravel 4 dựa trên nền Composer, nó có thể sử dụng những gói thư viện hữu dụng khác. Kết quả là, Laravel 4 phụ thuộc vào nhiều gói thư viện trong Symfony framework.

Nếu chúng ta nhìn vào source của Artisan tại Illuminate\Console\Application chúng ta có thể thấy được class Command được sử dụng rất nhiều những packages từ Symfony.

Folder chứa command

Khi chúng ta cài đặt một project Laravel, bạn sẽ thấy một thư mục mặc định app/commands. Thư mục này cũng được đặt mặc địch trong classmap của file composer.json. Vì vậy, khi bạn tạo một command mới chúng ta cần chạy composer dump-autoload. Nếu không chạy lệnh này, hệ thống sẽ báo lỗi cho bạn là class command của bạn không được tìm thấy.

Command Cơ bản

Một comamnd chỉ thực hiện một task duy nhất. Trong bài viết này, tôi xin giới thiệu ví dụ viết command cho người dùng. Cấu trúc cơ bản của một command được định nghĩa như sau:

// app/commands/UserGeneratorCommand.php

<?php

use Illuminate\Console\Command;

class UserGeneratorCommand extends Command {

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'user:generate';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = "Generate a new user";

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function fire()
    {
        $this->line('Welcome to the user generator.');
    }

}

Để tạo một command Class mới, chạy lệnh

    $ php artisan command:make UserGeneratorCommand

Sau command:make là tên của Class command bạn muốn tạo. Sau khi chạy lệnh này trong thư mục app/commands sẽ tạo cho bạn command class.

Hãy nghiên cứu một số thành phần có trong Class command trên:

  • Command Name: Tất cả các command cần được định nghĩa một tên. Tên này dùng để chạy command từ console. Trong khi không có bất kỳ một chuẩn đặt tên nào cho command, bạn có thể tham khảo một số cách sau: namespace:group/command, namespace:command, hoặc là command

  • Command Description: Tất cả comamnd cần có miêu tả. Mô tả sẽ được sử dụng khi lấy danh sách các lệnh từ Artisan. Nên mô tả ngắn gọn, dễ hiểu.

Cuối cùng để hoàn tất việc tạo mới một command chúng ta cần thêm command của mình để nó có sẵn sàng trong console. Mở file app/start/artisan.php thêm dòng sau vào cuối file

    $artisan->add(new UserGeneratorCommand);

Hoặc nếu bạn thích các cú pháp tĩnh

    Artisan::add(new UserGeneratorCommand);

Việc add này cho phép một command được cài đặt. Sau khi add, chúng ta có thể chạy lệnh

    $ php artisan user:generate
    Welcome to the user generator.

Xem thông tin hỗ trợ chúng ta chạy lệnh

    $ php artisan user:generate --help
Usage:
 user:generate

Options:
 --help (-h)           Display this help message.
 --quiet (-q)          Do not output any message.
 --verbose (-v)        Increase verbosity of messages.
 --version (-V)        Display this application version.
 --ansi                Force ANSI output.
 --no-ansi             Disable ANSI output.
 --no-interaction (-n) Do not ask any interactive question.
 --env                 The environment the command should run under.

Chú ý: Nếu bạn gặp bất kỳ lỗi nào, hãy thử chạy composer dump-autoload sau khi tạo mới command

Colored Output

Artisan cho phép xuất ra văn bản màu ngày trên màn hình console. Có các phương pháp như sau:

    $this->info("This is some information.");

    $this->comment("This is a comment.");

    $this->question("This is a question.");

    $this->error("This is an error.");

Và đây là kết quả:

1.png

Options and Arguments

Một khả năng thú vị của Artisan là cung cấp một câu lệnh với các tùy chọn và arguments

Arguments

Arguments là các chuỗi ký tự mà bạn truyền vào thông qua câu lệnh. Chúng cần được truyền vào command theo một thứ tự mà chúng được định nghĩa. Hãy xem ví dụ sau:

    $ php artisan user:generate [name] [email]

Argument name phải được khai báo trước argument email. Các Argument có thể được định nghĩa như những tùy chọn.

Options

Options được bắt đầu bằng -- khi định nghĩa:

    $ php artisan user:generate --admin

Defining Options and Arguments

Trước khi định nghĩa Arguments và Options, chúng ta cần import 2 class của Symfony đó là

    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Input\InputArgument;

Khi đó Class command của chúng ta sẽ như sau:

    // app/commands/UserGenerateCommand.php

    <?php

    use Illuminate\Console\Command;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Input\InputArgument;

    class UserGeneratorCommand extends Command {

        /**
         * The console command name.
         *
         * @var string
         */
        protected $name = 'user:generate';

        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = "Generate a new user";

        /**
         * Execute the console command.
         *
         * @return void
         */
        public function fire()
        {
            $this->line('Welcome to the user generator.');
        }

    }

Để định nghĩa options and arguments. Chúng ta cần khai báo 2 method mới là getArguments vả getOptions. Cả 2 method này đều trả về mảng cảu arguments và options. Hãy thử tạo cho command user của chúng ta có arguments name và options age

    // app/commands/UserGenerateCommand.php

    <?php

    use Illuminate\Console\Command;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Input\InputArgument;

    class UserGeneratorCommand extends Command {

        /**
         * The console command name.
         *
         * @var string
         */
        protected $name = 'user:generate';

        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = "Generate a new user";

        /**
         * Execute the console command.
         *
         * @return void
         */
        public function fire()
        {
            $this->line('Welcome to the user generator.');

            // Get the name arguments and the age option from the input instance.
            $name = $this->argument('name');

            $age = $this->option('age');

            $this->line("{$name} is {$age} years old.");
        }

        /**
         * Get the console command arguments.
         *
         * @return array
         */
        protected function getArguments()
        {
            return array(
                array('name', InputArgument::REQUIRED, 'Name of the new user'),
            );
        }

        /**
         * Get the console command options.
         *
         * @return array
         */
        protected function getOptions()
        {
            return array(
                array('age', null, InputOption::VALUE_REQUIRED, 'Age of the new user')
            );
        }

    }

Trong ví dụ trên, chúng ta nhìn thấy những thuộc tính của InputOption hay InputArgument hãy tìm hiều qua một chút về chúng nhé:

Với InputArgument:

  • InputArgument::REQUIRED : Bắt buộc phải truyền vào argument
  • InputArgument::OPTIONAL : Truyền hoặc không truyền argument

Với InputOption:

  • InputOption::VALUE_REQUIRED : Bắt buộc phải truyền vào option
  • InputOption::VALUE_OPTIONAL : Truyền hoặc không truyền option
  • InputOption::VALUE_IS_ARRAY : Option truyền vào là array
  • InputOption::VALUE_NONE :

Bây giờ hãy thử chạy command trên màn hình console của bạn. Thu được

    $ php artisan user:generate CanhNV --age=25
    CanhNV is 25 years old.

Argument Definitions

Định nghĩa cho một argument là một mảng có 4 key. Cụ thể:

  • Key 1: Tên của argument
  • Key 2: Chế độ tùy chọn, bắt buộc là 1 trong 2 giá InputArgument::REQUIRED (Bắt buộc phải truyền vào argument) và InputArgument::OPTIONAL (Truyền hoặc không truyền argument)
  • Key 3: Mô tả về argument
  • Key 4: là giá trị mặc định của argument
    array('name', InputArgument::OPTIONAL, 'Name of the new user', 'CanhNV')

Option Definitions

Tương tự như argument, định nghĩa cho option cũng là một mảng gồm có 5 key:

  • Key 1: Tên của option
  • Key 2: Là shortcut cho option
  • Key 2: Chế độ tùy chọn, bắt buộc là 1 trong 4 giá InputOption::REQUIRED (Bắt buộc phải truyền vào option), InputOption::OPTIONAL (Truyền hoặc không truyền option), InputOption::VALUE_IS_ARRAY, InputOption::VALUE_NONE.
  • Key 3: Mô tả về option
  • Key 4: là giá trị mặc định của option
    array('age', 'a', InputOption::VALUE_OPTIONAL, 'Age of the new user', 22)

Confirmations and Questions

Một tính năng mới của Artisan là khả năng yêu cầu xác nhận, hoặc thậm trí yêu cầu người sử dụng trả lời 1 câu hỏi.

Confirmations

Sử dụng confirm, chúng ta có thể hỏi người sử dụng một câu hỏi và khiến họ confirm với việc lựa chọn "yes" hoặc "no". Hãy thử với ví dụ người dùng confirm xem có nhập vào tuổi đúng hay không dưới đây

    // app/commands/UserGenerateCommand.php

    <?php

    use Illuminate\Console\Command;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Input\InputArgument;

    class UserGeneratorCommand extends Command {

        /**
         * The console command name.
         *
         * @var string
         */
        protected $name = 'user:generate';

        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = "Generate a new user";

        /**
         * Execute the console command.
         *
         * @return void
         */
        public function fire()
        {
            $this->line('Welcome to the user generator.');

            // Get the name arguments and the age option from the input instance.
            $name = $this->argument('name');

            $age = $this->option('age');

            if ( ! $this->confirm("Are you really {$age} years old? [yes|no]", true))
            {
                $this->comment('Then why did you say you were!?');

                return;
            }

            $this->comment("{$name} is {$age} years old.");
        }

        /**
         * Get the console command arguments.
         *
         * @return array
         */
        protected function getArguments()
        {
            return array(
                array('name', InputArgument::REQUIRED, 'Name of the new user'),
            );
        }

        /**
         * Get the console command options.
         *
         * @return array
         */
        protected function getOptions()
        {
            return array(
                array('age', null, InputOption::VALUE_REQUIRED, 'Age of the new user', null)
            );
        }

    }

Tham số đầu tiên là câu hỏi bạn muốn hỏi. Tham số thứ 2 là mặc định.

Questions

Sử dụng ask chúng ta có thể đưa ra câu hỏi cho người sử dụng và chờ họ trả lời. Thay vào dừng command khi người dùng nhập vào sai tuổi thì chúng ta có thể yêu cầu họ nhập lại tuổi của mình

    // app/commands/UserGenerateCommand.php

    <?php

    use Illuminate\Console\Command;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Input\InputArgument;

    class UserGeneratorCommand extends Command {

        /**
         * The console command name.
         *
         * @var string
         */
        protected $name = 'user:generate';

        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = "Generate a new user";

        /**
         * Execute the console command.
         *
         * @return void
         */
        public function fire()
        {
            $this->line('Welcome to the user generator.');

            // Get the name arguments and the age option from the input instance.
            $name = $this->argument('name');

            $age = $this->option('age');

            // Confirm the user entered their age correctly and if they haven't we'll
            // ask them to enter it again.
            if ( ! $this->confirm("Are you really {$age} years old? [yes|no]", true))
            {
                $age = $this->ask('So how old are you then?');
            }

            $this->comment("{$name} is {$age} years old.");
        }

        /**
         * Get the console command arguments.
         *
         * @return array
         */
        protected function getArguments()
        {
            return array(
                array('name', InputArgument::REQUIRED, 'Name of the new user'),
            );
        }

        /**
         * Get the console command options.
         *
         * @return array
         */
        protected function getOptions()
        {
            return array(
                array('age', null, InputOption::VALUE_REQUIRED, 'Age of the new user', null)
            );
        }

    }

Tổng kết

Khi bạn so sánh Artisan trong Laravel 4 với Laravel 3 bạn có thể dễ dàng nhận thấy sự cải tiến đáng kinh ngạc. Dựa vào Symfony Console mà sức mạnh của Artisan là vượt trội. Artisan đóng vai trò quan trọng, giúp chúng ta phát triển. Vì vậy hãy trang bị nó cho mình sớm nhé. ^^


All Rights Reserved

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