Ở bài trước chúng ta đã tìm hiểu qua về phương thức (method) trong PHP là gì và cách áp dụng vào các ví dụ trong bài, qua bài tiếp theo chúng ta sẽ tìm hiểu về Magic methods là gì, tìm hiểu về ứng dụng cũng như ưu và nhược điểm của Magic methods như thế nào nhé! Các bạn có thể xem lại khái niệm về phương thức (method) ở bài Class, properties, method of Object. Show Vấn đề tại sao mình lại giới thiệu về Magic method sớm trong series này như vậy bởi vì ở các bài tiếp theo các bạn sẽ phải đụng đến nó rất nhiều, các bạn cần phải hiểu và áp dụng được nó trong lập trình PHP để thao tác và học đến các bài kế tiếp nhé! Magic methods là gì?Magic methods là các phương thức đặc biệt để tùy biến các các sự kiện (event) khi chúng ta thao tác tới đối tượng trong php. Hiểu đơn giản là nó cung cấp thêm cách để giải quyết một vấn đề. Magic methods được dùng để xử lý các đối tượng trong lập trình hướng đối tượng giúp ta sử dụng các đối tượng dễ dàng hơn. Bài 3: Magic methods trong PHP Thông thường mỗi magic method sẽ được kích hoạt (trigger) ở một sự kiện nào đó mà ta tác động vào đối tượng. Ví dụ hàm <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi7 và <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi8 sẽ được gọi khi ta tiến hành gán hay lấy giá trị của các thuộc tính trong đối tượng. Và vì nó có tính đặc biệt nên bạn dễ dàng nhận biết nó qua hai dấu gạch dưới (__), nghĩa là tất cả các phương thức Magic methods đều có tên bắt đầu bằng hai dấu gạch dưới. Danh sách một số magic methods PHP cần quan tâm
Các bạn có thể tham khảo chi tiết thêm tại php.net Về chi tiết của từng loại magic method mình sẽ nêu rõ ở các bài viết sau và cập nhật lại cho các bạn. Ưu điểm và nhược điểm của magic methods PHPƯu điểmTừ khái niệm trên thì các bạn chắc cũng có thể nhận ra các ưu điểm của nó rồi chứ? nó gồm có các ưu điểm như sau:
Nhược điểmNhược điểm của magic methods là có tốc độ chậm hơn các phương thức bình thường. Ví dụ một số magic methods PHP__construct()Hàm được gọi khi ta khởi tạo một đối tượng. <?php class A { public function __construct($text) { echo "$text"; } } $tweet = new A('Hello World'); Không giống như các ngôn ngữ lập trình hướng đối tượng như java hay C#. Trong PHP, hàm khởi tạo không cho phép chúng ta thực hiện việc overload, nó chỉ cho phép khởi tạo 1 đối tượng duy nhất ứng với method __contructs() được khai báo trong class(không khai báo mặc định là không truyền gì). <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi Chúng ta thấy nó không thể khởi tạo được biến thứ 2 do method __contruct() ta có tham số truyền vào. Để khắc phục việc không cho overload, trong php có tùy biến như sau : <?php class A { public function __construct(...$text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); Chỉ cần thêm ba chấm trước biến được truyền vào thì sẽ không còn bug nữa. __destruct()Được gọi khi một đối tượng bị hủy. Mặc định khi kết thúc chương trình hoặc khi ta khai báo mới đối tượng đó sẽ bị hủy bỏ và gọi đến method __destruct(). <?php class A { public function __construct(...$text) { $this->text = $text; } public function __destruct() { echo '<br>'; echo "Huy doi tuong co " . count($this->text) . ' tham so truyen vao.'; } } $tweet = new A('2', '5'); // so luong tham so truyen vao la 2 $var = new A(); // so luong tham so truyen vao la 0 $test = new A('60'); // so luong tham so truyen vao la 1 echo 'End'; Như trên ví dụ ta có thể thấy đối tượng tạo trước sẽ bị hủy sau khi chương trình kết thúc. __set()Gọi khi ta truyền dữ liệu vào thuộc tính không tồn tại hoặc thuộc tính private trong đối tượng. <?php class A { public function __set($key, $value) { echo "$key <br> $value"; } } $tweet = new A(); $tweet->name = 'Dao Cong Van'; /* output: name Dao Cong Van */ Nó truyền dưới dạng key => value. Như ở ví dụ trên, ta set giá trị cho thuộc tính name mà không tồn tại trong class. Nó sẽ gọi đến hàm __set() với $key là thuộc tính đã gọi, $value là giá trị đã gán. __get()Gọi khi ta truy cập vào thuộc tính không tồn tại hoặc thuộc tính private trong đối tượng. Tương tự như set, get là việc xử lý khi truy cập đối tượng. <?php class A { public function __get($key) { echo "Xin chao $key"; } } $tweet = new A(); $tweet->people; /* output: Xin chao people */ __isset()Phương thức __isset() sẽ được gọi khi chúng ta thực hiện kiểm tra một thuộc tính không được phép truy cập của một đối tượng, hay kiểm tra một thuộc tính không tồn tại trong đối tượng đó. Cụ thể là hàm isset() và hàm empty(). Chú ý: phương thức __isset() không sử dụng được với thuộc tính tĩnh. <?php class A { public function __isset($key) { echo "Thuoc tinh kiem tra khong ton tai: $key"; } } $tweet = new A(); isset($tweet->people); /* output: Thuoc tinh kiem tra khong ton tai: people */ __unset()Được gọi khi hàm unset() được sử dụng trong một thuộc tính không được phép truy cập. Tương tự như hàm isset. Khi ta Unset 1 thuộc tính không tồn tại thì method __unset() sẽ được gọi. <?php class A { public function __unset($key) { echo "Thuoc tinh kiem tra khong ton tai: $key"; } } $tweet = new A(); unset($tweet->people); /* output: Thuoc tinh kiem tra khong ton tai: people */ __call()Được gọi khi ta gọi một phương thức không được phép truy cập trong phạm vi của một đối tượng. Như vậy thì có thể thấy __get() và __call() cũng gần giống nhau. Có điều __get() gọi khi không có thuộc tính còn __call() khi phương thức không có. Ta cũng có thể dùng hàm __call() để thực hiện overload trong php. Khai báo : __call($method_name, $parameter) Trong đó:
<?php class A { public function __call($method_name, $parameter) { if ($method_name == "overloadFunction") { $count = count($parameter); switch ($count) { case "1": echo 'code cho moi doi so'; break; case '2': echo 'Code cho 2 doi so'; break; default: throw new Exception('Bad argument'); } } else { throw new Exception('Function $method_name does not exists'); } } } $var = new A(); $var->overloadFunction('1'); echo '<br>'; $var->overloadFunction('2'); echo '<br>'; $var->overloadFunction('2', '3'); /*output: code cho moi doi so code cho moi doi so Code cho 2 doi so */
Chúng ta có thể thấy trong class test không hề có hàm overloadFunction. Khi ta gọi tới phương thức overloadFunction thì nó sẽ chạy hàm __call(). __callstatic()Được kích hoạt khi ta gọi một phương thức không được phép truy cập trong phạm vi của một phương thức tĩnh. <?php class A { public static function __callStatic($name, $arguments) { echo "Ban vua goi phuong thuc " . $name . " va co cac tham so: " . implode(' - ', $arguments); } } A::getInfo('name', 'age', 'address'); /* output: Ban vua goi phuong thuc getInfova co cac tham so: name - age - address */ __toString()Phương thức này được gọi khi chúng ta in echo đối tượng. Method __toString() sẽ bắt buộc phải trả về 1 dãy String. <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi0 __invoke()Phương thức này được gọi khi ta cố gắng gọi một đối tượng như một hàm. <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi1 __Sleep()Được gọi khi serialize() một đối tượng. Thông thường khi chúng ta serialize() một đối tượng thì nó sẽ trả về tất cả các thuộc tính trong đối tượng đó. Nhưng nếu sử dụng __sleep() thì chúng ta có thể quy định được các thuộc tính có thể trả về. <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi2 __wakeupĐược gọi khi unserialize() đối tượng. <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi3 __set_state()Được sử dụng khi chúng ta var_export một object. <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi4 __clone()Được sử dụng khi chúng ta clone(sao chép 1 đối tượng thành 1 đối tượng hoàn toàn mới không liên quan đến đối tượng cũ) một object. <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi5 __debugInfo()Được gọi khi chúng ta sử dụng hàm vardump(). <?php class A { public function __construct($text) { echo 'So luong tham so truyen vao: '. count($text); } } $tweet = new A('Hello World','Hi'); // so luong tham so truyen vao la 2 echo '<br>'; $var = new A(); //sẽ xảy ra lỗi6 Kết thúcBài viết đã tổng quan về magic methods và cách sử dụng chúng. Việc sử dụng magic methods khá là hữu ích nhưng chúng ta cũng không nên lạm dụng vì nó chậm hơn methods thường. Về một số magic method quan trọng trong PHP mình sẽ có những bài viết riêng về chúng ở những bài sau cho các bạn tham khảo nhé! Xem thêm:
|