Reflection và Reverse Engineering trong PHP
PHP
78
White

Vu Nhat Minh viết ngày 27/05/2015

Giới thiệu Reflection class trong PHP

Kể từ PHP 5 trở đi, Programmer PHP đã có bộ API Reflection rất hữu dụng để reverse-engineering các class, interfaces, function hay các extension. Bài viết này sẽ giới thiệu tính năng, ý nghĩa và ứng dụng của Reflection trong PHP.

Thế nào là dynamically-typed language ?

Cũng giống như Python hay Ruby, PHP là một dynamically-typed language.

Chúng ta hãy cùng xem xét 2 class sau:

<?php
class Author 
{
    private $name;
    private $birth;

    public function __construct($name, $birth)
    {
        $this->name = $name;
        $this->birth = $birth;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getBirth()
    {
        return $this->birth;
    }

}
?>
<?php
class Book 
{
    private $author;
    public function setAuthor($author)
    {
        $this->author = $author; 
    }
    public function getAuthor()
    {
        return $this->author;
    }
}

?>

2 class rất đơn giản phải không :) Book hoàn toàn có thể được setAuthor() là 1 string hay là 1 instance của class Author. Không khó để hình dung ra kết quả của đoạn code dưới đây.

<?php
$book1 = new Book;
$book1->setAuthor("Nam Cao");
var_dump($book1->getAuthor());

$book2 = new Book;
$book2->setAuthor(new Author("Nam Cao","29-10-1915"));
var_dump($book1->getAuthor());
?>

Nếu chỉ dừng ở đây thì tôi với bạn chẳng có gì để nói với nhau :D Nhưng bạn hãy thử để ý, 1 instance của 1 class Book khi gọi đến hàm setAuthor hoàn toàn không có 1 khái niệm nào về $author cả. Nói cách khác, $author có thể là bất cứ 1 object nào. Điều gì sẽ xảy ra khi tôi modify class Book 1 chút như sau:

<?php
class Book 
{
    private $author;
    public function setAuthor($author)
    {
        $this->author = $author; 
        var_dump($author->getName()); // Attention here! Now we try to call getName() of variable $author
    }
    public function getAuthor()
    {
        return $this->author;
    }
}

?>

Bạn thử chạy lại đoạn code bên trên với class Book mới, bạn sẽ thấy $book1 trả về Fatal Error nhưng $book2 sẽ chạy qua bình thường!

Vào thời điểm runtime $book2, PHP sẽ "inspect" object $author truyền vào cho setAuthor() và tự hiểu $author là 1 instance của class Author và có 1 method là getName().

Reverse engineering example

Vậy PHP nói riêng và các dynamically-typed language nói chung làm thế nào để nhận biết được type của object truyền vào là function hay class ?

Câu trả lời là reflection class! Bạn đã nhận ra PHP dùng reflection như thế nào qua ví dụ bên trên, bạn thậm chí có thể tự sử dụng reflection class.

<?php
class Book 
{
    private $author;
    public function setAuthor($author)
    {
        $this->author = $author; 
        var_dump($author->getName()); // original name
        $reflector = new ReflectionClass($author); // Here we start to inspect $author
        $authorName = $reflector->getProperty('name'); // Get local variable 'name'
        $authorName->setAccessible(true); // since 'name' is a private local variable of class Author, we need access here to modify 
        $authorName->setValue($author,'Ngo Tat To'); // now hack the 'name' of $author :))
        var_dump($author->getName()); // Guess what will be output here :D 
    }
    public function getAuthor()
    {
        return $this->author;
    }
}


?>

Bạn thử đoán xem đoạn var_dump sau sẽ ra kết quả gì :D

<?php
$book2 = new Book;
$book2->setAuthor(new Author("Nam Cao","29-10-1915"));
var_dump($book1->getAuthor()); // Suprisingly, 'Ngo Tat To', not 'Nam Cao' here 
?>

Reflection class dùng để làm gì ?

Đến đây có lẽ bạn đọc đã hình dung ra phần nào cách thức hoạt động của reflection class, các ngôn ngữ dynamically-typed "hiểu" các object như thế nào. Reflection thực tế tồn tại trong PHPUnit hay các mocking framework, các code analysis framwworks hay metaprogramming.

Reflection class trong PHP là 1 tool mạnh mẽ cung cấp cho programmer chính những sức mạnh mà ngôn ngữ sở hữu. Tuy nhiên reflection class không hề được khuyến khích dùng rộng rãi, vì với bản chất là tool của quá trình reverse engineering, nó hoàn toàn có thể làm design của hệ thống trở nên mess up và khó kiểm soát.

Reflection chỉ nên dùng khi nào thực sự cần thiết, ứng dụng nhìn thấy rõ nhất là khi bạn phải "đối đầu" với 1 project mà document ko đầy đủ hay không được upadte thường xuyên. Cake Api Generator là ví dụ điển hình nhất.

Summary

  • Dynamically-typed language: Là ngôn ngữ có thể tự hiểu được object tại thời điểm runtime, không cần tại compile time. PHP, Ruby, Python là dynamically-typed language. Ngược lại C hay Java là statically typed language.
  • Reflection Class Là 1 bộ API được PHP cung cấp để sử dụng kỹ thuật reverse engineer, hữu dụng khi tạo document tự động.
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Vu Nhat Minh

54 bài viết.
775 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
119 30
Nếu bạn thường vào trang mua sắm của amazon, chắc sẽ chẳng lạ gì với menu Shop by Department. Tốc độ hiển thị nội dung của menu là tức thì so với d...
Vu Nhat Minh viết gần 3 năm trước
119 30
White
93 4
Lời người dịch Người dịch là một developer , sau khi tìm đọc được bài viết này bằng bản gốc tiếng Anh đã cảm thấy như được "khai sáng" về khả năng...
Vu Nhat Minh viết 3 năm trước
93 4
White
61 7
Form là thành phần quan trọng nhất khi design flow đăng ký của 1 web hay 1 app, dù là view gồm nhiều bước hay chỉ là một màn hình đơn điệu. Bài này...
Vu Nhat Minh viết hơn 1 năm trước
61 7
Bài viết liên quan
White
2 2
Bash script to fast serve Laravel project Lười gõ dòng lệnh quá nên tạo ra cái script để gõ nhanh :D laravelstart.sh /bin/bash if z "$1" ] ...
Vũ Hoàng Chung viết hơn 1 năm trước
2 2
Male avatar
9 1
Để bắt đầu làm thêm của riêng bạn thì ban đầu bạn phải có một theme trắng ( Blank theme ) để bắt đầu Theme trắng là gồm có các thư mục và file cơ b...
Doan Van Manh viết hơn 2 năm trước
9 1
Male avatar
1 0
Một ngày nào đó, bạn mới dựng source code lên. Bạn luôn hi vọng khi vào site sẽ hiển thị đẹp mắt và yếu tố đẹp mắt ban đầu sẽ là text của site của ...
skul169 viết gần 2 năm trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
54 bài viết.
775 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!