12/08/2018, 14:56

Symfony components: OptionsResolver

Mình là một PHP programmer nhưng bài viết viết PHP lại khá ít (03/19 bài). Sau một khoảng thời gian viết về các ngôn ngữ linh tinh, hôm nay mình sẽ quay về với ngôn ngữ mà có lẽ là mình thạo nhất nhé. Chẳng là vừa rồi mình có viết một PHP package làm việc với OneSignal API. Nên mình có tìm hiểu ...

Mình là một PHP programmer nhưng bài viết viết PHP lại khá ít (03/19 bài). Sau một khoảng thời gian viết về các ngôn ngữ linh tinh, hôm nay mình sẽ quay về với ngôn ngữ mà có lẽ là mình thạo nhất nhé. Chẳng là vừa rồi mình có viết một PHP package làm việc với OneSignal API. Nên mình có tìm hiểu và sử dụng đến một component của Symfony để validate các tham số truyền vào, đó là Symfony OptionsResolver. Mình thấy nó khá hay và tiện nên viết bài giới thiệu tới mọi người. Hy vọng sẽ giúp cho mọi người có một sự lựa chọn khi có chung một mục đích giống mình. Chúng ta cùng tìm hiểu xem Symfony OptionsResolver là gì, làm việc như thế nào và được ứng dụng ra sao nhé ^^

Symfony OptionsResolver

Symfony OptionResolver component giống như hàm array_replace. Nó cho phép bạn tạo một hệ thống các tùy chọn với các tùy chọn bắt buộc, các giá trị mặc định, kiểm tra (kiểu dữ liệu, giá trị dữ liệu), tạo chuẩn cho dữ liệu đầu ra, ...

Cài đặt

Để cài đặt package này, bạn có thể làm theo 2 cách:

  • Sử dụng Composer thông qua Packagist với lệnh: composer require symfony/options-resolver
  • Clone repository của OptionsResolver tại địa chỉ: https://github.com/symfony/options-resolver

Sau đó, bạn chỉ cần require file vendor/autoload.php để sử dụng.

Sử dụng

Bây giờ, chúng ta cùng sử dụng ví dụ ở trang chủ của Symfony để tìm hiểu cách hoạt động và tính ứng dụng của component này nhé. Chúng ta có một class sử dụng để email. Class này có các tham số cài đặt là host, username, password và port để cài đặt.

class Mailer
{
    protected $options;

    public function __construct(array $options = array())
    {
        $this->options = $options;
    }
}

Khi sử dụng, chúng ta cần truy cập các thông số cài đặt. Chúng ta cần phải xử lý rất nhiều nghiệp vụ logic để kiểm tra các cài đặt đó. Xem nó có tồn tại và hợp lệ hay không:

class Mailer
{
    // ...
    public function sendMail($from, $to)
    {
        $mail = ...;

        $mail->setHost(isset($this->options['host'])
            ? $this->options['host']
            : 'smtp.example.org');

        $mail->setUsername(isset($this->options['username'])
            ? $this->options['username']
            : 'user');

        $mail->setPassword(isset($this->options['password'])
            ? $this->options['password']
            : 'pa$$word');

        $mail->setPort(isset($this->options['port'])
            ? $this->options['port']
            : 25);

        // ...
    }
}

Với đoạn code trên, bạn có thể thấy nó rất khó để đọc, lặp đi lặp lại các câu lệnh logic để kiểm tra? Giống như lời giới thiệu ban đầu, là chúng ta có thể sử dụng method array_replace của PHP để xử lý việc này:

class Mailer
{
    // ...

    public function __construct(array $options = array())
    {
        $this->options = array_replace(array(
            'host'     => 'smtp.example.org',
            'username' => 'user',
            'password' => 'pa$$word',
            'port'     => 25,
        ), $options);
    }
}

Đoạn trên thì code của chúng ta đã sáng sủa hơn, đúng không ạ. Nhưng sẽ ra sao khi chúng ta viết nhầm tên của một tùy chọn như:

$mailer = new Mailer(array(
    'usernme' => 'johndoe',  // usernAme misspelled
));

Đoạn code trên không gây ra lỗi. Nhưng nó sẽ phát sinh ra bug. Và chúng ta sẽ mất kha khá thời gian để tìm hiểu nguyên nhân để xử lý (do lỗi typo, và lỗi này khá là khó tìm đấy nhể :v?). Vậy nếu sử dụng OptionsResolver, những bất cập mà chúng ta đưa ra từ nãy đến giờ có giải quyết được không? Có dễ dàng và đơn giản để sử dụng hay không? Chúng ta cùng thử nhé             </div>
            
            <div class=

0