PDF:

Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao
diện đối tượng
John Mertic
Kỹ sư phần mềm
SugarCRM
06 11 2009
PHP V5.3 lên lịch phát hành sớm. Nhiều đặc tính mới trong bản pabstracthát hành này đã trong
các giai đoạn kế hoạch trong vài năm. Được chào bán ban đầu như một “PHP V6 không có trợ
giúp mã Unicode gốc”, PHP V5.3 đã được phát triển thành một bản nâng cấp với nhiều đặc tính
cho dòng PHP V5. Nó được thiết kế làm một bản phát hành để chuẩn bị cho các nhà phát triển
PHP V6 khi nó xuất hiện với nhiều đặc tính mới, làm sạch các đặc tính hiện tại bằng cách thay
đổi chút ít (tweaking) các chức năng, cố định khía cạnh về nền đặc biệt, và loại bỏ các tính năng
cũ mà sẽ không còn trong các bản sau này của PHP. Trong loạt bài "Có gì mới trong PHP V5.3"
này, chúng ta sẽ xem xét các đặc tính mới của bản V5.3, và xem cách chúng được dùng, cũng
như cách dùng chúng trong ứng dụng web của bạn.
Xem thêm bài trong loạt bài này
PHP V5 và lập trình hướng đối tượng
Khi PHP V5 được phát hành vào năm 2004, nó đã là một bước đại nhảy vọt so với những gì mà
PHP V4 cung cấp về mặt thiết kế và lập trình hướng đối tượng OOP (object-oriented program). Nó
bổ sung một vài cải tiến cần thiết, thí dụ như khả năng nhìn thấy lớp (class visibility), các bộ dựng
(constructors) và các bộ huỷ (destructors) phù hợp, các gợi ý về kiểu, và API phản ảnh lớp (classreflection API). Nó mở ra cánh cửa cho việc lập trình hướng đối tượng tiên tiến trong PHP, và cho
phép bạn thực hiện nhiều mẫu thiết kế dễ hơn nhiều, cùng với các lớp thiết kế và các API tốt hơn.
Trong PHP V5.3, nhiều bổ sung gia tăng đã được đưa vào nhằm tăng cường OOP. Những cải tiến
này đã nằm trong lĩnh vực bổ sung cú pháp và cải tiến hiệu năng. Để bắt đầu, chúng ta hãy quan
sát các đặc tính mới sẵn có với các phương thức và thành viên tĩnh.
Các phương thức tĩnh được cải thiện và quản lí thành viên (member
handling)
Một bổ sung hữu ích trong PHP V5 là khả năng quy định một phương thức hoặc thành viên của
một lớp là tĩnh (PHP V4 thực hiện hỗ trợ truy cập tĩnh đến các phương thức và các thành viên của
© Copyright IBM Corporation 2009
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Nhẫn hiệu đăng ký
Trang 1 của 10
developerWorks®
ibm.com/developerWorks/vn/
lớp, nhưng không có khả năng quy định rằng phương thức hoặc thành viên đó được thiết kế để truy
cập tĩnh). Truy cập tĩnh đặc biệt rất hữu ích để thực hiện mẫu thiết kế đơn lẻ (singleton design), nơi
chỉ tồn tại một thực thể của lớp.
PHP V5.3 đã thêm vào một số đặc tính để tăng cường trợ giúp các thành viên và các phương thức
tĩnh trong một lớp. Đầu tiên chúng ta sẽ quan sát một phương thức ma thuật vừa được thêm vào:
__callStatic().
Phương thức ma thuật _callStatic()
PHP V5 có một số phương thức được xác định một cách đặc biệt, có thể sử dụng bên trong các lớp
gọi là các phương thức ma thuật (magic methods). Khi được xác định trong lớp, các phương thức
này cung cấp các chức năng đặc biệt, và có khả năng chịu tải (khả năng cho phép một phương
thức chấp nhận các kiểu tham số khác nhau) và tính đa dạng (polymorphism) (khả năng cho phép
các kiểu dữ liệu khác nhau sử dụng cùng một giao diện). Chúng cũng mở cánh cửa cho việc sử
dụng các kiểu khác nhau của các phương thức lập trình OOP và các mẫu thiết kế bằng PHP một
cách dễ dàng.
Trong PHP V5.3 có một phương thức ma thuật mới được thêm vào: __callStatic(). Nó làm
việc tương tự như phương thức ma thuật __call() được thiết kế để xử lý các cuộc gọi ra phương
thức cho các phương thức mà không được xác định hoặc nhìn thấy được trong lớp. Tuy nhiên,
__callStatic() được thiết kế để xử lý các cuộc gọi ra phương thức tĩnh, chúng cho chúng ta khả
năng thiết kế tốt hơn sự quá tải về phương thức của chúng ta. Một ví dụ về cách sử dụng phương
thức này như dưới đây.
Liệt kê 1. Ví dụ về việc sử dụng __callStatic() đối với __call()
class Foo
{
public static function __callStatic(
$name,
$args
)
{
echo "Called method $name statically";
}
public function __call(
$name,
$args
)
{
echo "Called method $name";
}
}
Foo::dog();
$foo = new Foo;
$foo->dog();
// outputs "Called method dog statically"
// outputs "Called method dog"
Một điều cần lưu ý là PHP thực hiện áp đặt định nghĩa của phương thức __callStatic(); nó phải
là chung (public), và nó phải được tuyên bố là tĩnh. Cũng như vậy, phương thức ma thuật __call()
cũng phải được xác định là chung, đúng như tất cả các phương thức ma thuật phải là như vậy.
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 2 của 10
ibm.com/developerWorks/vn/
developerWorks®
Các cuộc gọi ra tĩnh động
Một đặc tính rất hay của PHP là các biến cho biến (variable variables). Điều có nghĩa là bạn có thể
sử dụng chuỗi giá trị của một biến để quy định tên của một biến khác. Nói một cách khác, bạn có
thể thực hiện việc gì đó giống như dưới đây.
Liệt kê 2. Các biến “biến” (Variable variables)
$x = 'y';
$$x = 'z';
echo $x; // outputs 'y'
echo $y; // outputs 'z'
echo $$x; // outputs 'z'
Cùng một khái niệm có thể được sử dụng với các hàm, hoặc thậm chí các phương thức lớp như
dưới đây.
Liệt kê 3. Tên các hàm biến và phương thức lớp
class Dog
{
public function bark()
{
echo "Woof!";
}
}
$class = 'Dog'
$action = 'bark';
$x = new $class(); // instantiates the class 'Dog'
$x->$action();
// outputs "Woof!"
Điểm mới ở PHP V5.3 là khả năng có tên của lớp khi được quy định là một biến khi thực hiện một
cuộc gọi tĩnh. Việc này mở ra một vài khả năng mới, như dưới đây.
Liệt kê 4. Đặt tên lớp biến
class Dog
{
public static function bark()
{
echo "Woof!";
}
}
$class = 'Dog';
$action = 'bark';
$class::$action();
//outputs "Woof!"
Bổ sung này tạo ra khía cạnh về các biến của biến trong PHP đầy đủ, cho phép dùng chúng chỉ
trong từng tình huống với PHP.
Chúng ta hãy quan sát một cải tiến hữu ích hơn cho việc sử dụng các phương thức và thành viên
tĩnh: liên kết tĩnh muộn (late static binding).
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 3 của 10
developerWorks®
ibm.com/developerWorks/vn/
Liên kết tĩnh muộn
Một trong những điều phiền phức nhất về PHP trước V5.3 là cách phương thức và thành viên tĩnh
được xử lý. Cho đến nay, các tham chiếu tĩnh (static references), chẳng hạn như các tham chiếu
được làm bản thân nó hoặc __CLASS__, được giải quyết trong phạm vi lớp, trong đó hàm được định
nghĩa. Vấn đề là ở chỗ tham chiếu sẽ không đúng nếu lớp được mở rộng và cuộc gọi được thực hiện
từ lớp con (child class) mới. Liên kết tĩnh muộn đã được thêm vào PHP V5.3 để giảm bớt vấn đề
này. Để minh hoạ rõ hơn, chúng ta hãy tạo ra một lớp với một phương thức tĩnh dưới đây.
Liệt kê 5. Lớp Foo với phương thức tĩnh test()
class Foo
{
protected static $name = 'Foo';
public static function test()
{
return self::$name;
}
}
Chúng ta hãy mở rộng lớp này. Chúng ta sẽ định nghĩa lại thành viên $name trong lớp con này.
Liệt kê 6. Lớp con Bar mở rộng lớp cha Foo
class Bar extends Foo
{
protected static $name = 'Bar';
}
Chúng ta thực hiện cuộc gọi tĩnh trong Liệt kê 7.
Liệt kê 7. Các cuộc gọi phương thức tĩnh test()
echo Bar::test();
Kết quả từ cuộc gọi đó sẽ là chuỗi Foo. Đây là do tham chiếu self::$name thực hiện trong phương
thức test() được thực hiện bằng lớp Foo. Liên kết xuất hiện bằng cách này vì đây là nơi hàm được
định nghĩa.
PHP V5.3 đã thêm từ khoá static để cho phép bạn thực hiện một tham chiếu đối với lớp hiện tại.
Do đó bạn sẽ thay đổi lớp Foo trên để sử dụng từ khoá này trong Liệt kê 8, và chúng ta sẽ thấy rằng
Bar sẽ thay vào kết quả.
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 4 của 10
ibm.com/developerWorks/vn/
developerWorks®
Liệt kê 8. Sử dụng từ khoá static
class Foo
{
protected static $name = 'Foo';
public static function test()
{
return static::$name;
}
}
class Bar
{
protected static $name = 'Bar';
}
echo Bar::test(); // outputs 'Bar'
Một điều cần lưu ý về từ khoá static là nó không làm việc như cách làm trong ngữ cảnh không
tĩnh. Điều này có nghĩa là các nguyên tắc kế thừa bình thường không áp dụng với các cuộc gọi tĩnh.
Từ khoá static sẽ chỉ cần cố gắng giải quyết cuộc gọi trong lớp hiện tại thay cho lớp mà hàm được
định nghĩa. Đây là một điều quan trọng cần lưu ý.
Bây giờ chúng ta đã thấy một vài cải tiến với các phương thức và thành viên tĩnh, hãy quan sát một
vài lớp mới được bổ sung vào bộ phận rất hữu ích của PHP V5, là Thư viện lớp PHP chuẩn.
Thư viện lớp PHP chuẩn
Thư viện lớp PHP chuẩn (SPL) là một tập các giao diện và các lớp thêm vào PHP V5, được thiết kế
để giải quyết các vấn đề chuẩn. Các vấn đề này gồm việc cho một đối tượng được lặp (iterateable),
cho phép một đối tượng đối xử cứ như một mảng, hoặc thực hiện một danh sách móc nối. Lợi điểm
của việc sử dụng các lớp và các phương thức này là ở chỗ chúng là riêng cho PHP, nghĩa là chúng
sẽ nhanh hơn nếu chúng được thực hiện trong chính PHP. Chúng cũng, trong nhiều ví dụ, cho phép
nhiều hàm trong của PHP sử dụng các đối tượng trực tiếp này, chẳng hạn như cách giao diện biến
lặp (Iterator interface) cho phép bạn sử dụng cấu trúc foreach để lặp lại trên đối tượng.
PHP V5.3 thêm khá nhiều lớp vào SPL. Có một điều chúng ta đã tham khảo trước đây là cài đặt
danh sách móc nối kép (doubly linked list) trong lớp SPL SplDoublyLinkedList. Nó được sử dụng
bởi hai lớp SPL mới khác: SplStack, cài đặt stack (vùng nhớ xếp chồng), và SplQueue, cài đặt hàng
đợi.
Chúng ta hãy quan sát cách bạn có thể sử dụng lớp SplStack để thực hiện một vùng nhớ.
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 5 của 10
developerWorks®
ibm.com/developerWorks/vn/
Liệt kê 9. Sử dụng SplStack
$stack = new SplStack();
// push a few new items on the stack
$stack->push('a');
$stack->push('b');
$stack->push('c');
// see how many items are on the stack
echo count($stack); // returns 3
// iterate over the items in the stack
foreach ( $stack as $item )
echo "[$item],";
// the above outputs: [c],[b],[a]
// pop an item off the stack
echo $stack->pop(); // returns 'c'
// now see how many items are on the stack
echo count($stack); // returns 2
làm việc theo kiểu tương tự, nhưng nó làm việc như một hàng đợi (vào trước, ra trước;
chứ không phải là vào sau, ra trước, như là stack. Ngoài ra, còn cài đặt đống (SplHeap), cũng như
là hàng đợi riêng và các cài đặt đống cho vài tình huống nhất định (SplMinHeap, SplMaxHeap và
SplPriorityQueue).
SqlQueue
Một bổ sung hữu ích nữa là lớp SplFixedArray mà như tên đã ngụ ý, là cài đặt mảng kích thước cố
định. Tất nhiên nó khá nhanh — thực ra là nhanh đến mức được đo thử chuẩn, nhanh hơn 10-30%
so với cài đặt mảng lắp sẵn trong PHP. Sự tăng tốc này là do việc mảng này có một kích thước cố
định, không thay đổi như PHP mặc định, và do không được phép sử dụng các chỉ mục phi số. Liệt
kê 10 chỉ ra cách nó được sử dụng.
Liệt kê 10. SplFixedArray
$array = new SplFixedArray(3);
$array[0] = 'dog';
$array[1] = 'cat';
$array[2] = 'bird';
$a->setSize(4); // increase the size on the fly
$array[3] = 'mouse';
foreach ( $array as $value )
echo "[$value],";
Output:
[dog],[cat],[bird],[mouse]
Ngoài ra còn có một vài lớp biến lặp mới đã được thêm vào: FilesystemIterator và GlobIterator.
Các biến này làm việc như các lớp biến lặp khác trong PHP, nhưng chúng được thiết kế đặc biệt
dùng cho vài cá thể nhất định.
Một thay đổi nữa với SPL là ở chỗ bây giờ nó luôn được kích hoạt trong PHP V5.3. Trong các
phiên bản trước của PHP V5, bạn có thể vô hiệu hoá SPL vào lúc dịch, nhưng đối với PHP V5.3,
việc này không còn cho phép.
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 6 của 10
ibm.com/developerWorks/vn/
developerWorks®
Các bổ sung mới cho SPL thêm một số chức năng hữu ích vào PHP rất dễ sử dụng, cũng như các
bổ sung về cấu trúc dữ liệu, thí dụ như các danh sách móc nối kép, stack, heap, và hàng đợi. Các
lớp này có thể được sử dụng để thay thế các cài đặt không gian người dùng mà bạn có thể có,
chúng sẽ thu được tốc độ gia tăng và sự kết hợp tốt hơn với các cấu trúc và hàm PHP khác nhau.
Giờ chúng ta đã thấy một vài bổ sung mới cho SPL, hãy xem cách OOP trong PHP V5.3 đã thu
được một hiệu năng quan trọng và cải thiện việc sử dụng bộ nhớ với bổ sung việc gom rác xoay
vòng (circular garbage collection).
Gom rác xoay vòng
Một vấn đề mà các nhà phát triển PHP gặp phải trên quan điểm hiệu năng là việc gom rác
(garbage collection). PHP có một bộ gom rác khá đơn giản, mà về cơ bản sẽ thu thập rác cho một
đối tượng khi nó không còn nằm trong phạm vi hợp lệ. Cách mà nó thực hiện việc này về mặt nội tại
là bằng cách sử dụng một bộ đếm quy chiếu (reference counter), để khi bộ đếm chạm 0 (có nghĩa
là không còn các quy chiếu đến đối tượng này nữa), đối tượng sẽ được thu gom và gạch bỏ từ bộ
nhớ.
Việc này khá tốt, nhưng có thể trở thành một vấn đề trong các tình thế khi một đối tượng quy chiếu
đến một đối tượng khác theo quan hệ cha-con (parent-child relationship). Với tình tình thế này, bộ
đếm quy chiếu đối với các đối tượng đó không được thu gom, nên bộ nhớ sử dụng bằng đối tượng
này lưu lại trong bộ nhớ không quy chiếu (unreferenced memory) và không được ngừng cấp phát,
cho đến khi kết thúc yêu cầu. Chúng ta hãy quan sát một ví dụ khi vấn đề này xảy ra.
Liệt kê 11. Quan hệ lớp cha-con bị thu gom rác không phù hợp trong bản PHP
V5.2 và bản trước đó
class Parent
{
public function __construct()
{
$this->child = new Child($this);
}
}
class Child
{
public function __construct(
Parent $parent
)
{
$this->parent = $parent;
}
}
Trong ví dụ này, mỗi khi bạn tạo ra một cá thể của lớp Parent và sau đó cá thể tiếp theo không
còn nằm trong phạm vi hợp lệ, bộ nhớ không bao giờ được giải phóng, như vậy kịch bản lệnh sẽ
ngày càng lớn thêm trong việc sử dụng bộ nhớ. Có một số giải pháp về không gian người dùng đối
với vấn đề này, chẳng hạn như tạo một hàm huỷ cho lớp cha mà sẽ trực tiếp giải phóng đối tượng
con. Hàm huỷ này sẽ phải được gọi ra riêng trước khi bỏ thiết đặt quy chiếu lớp cha (parent class
reference). Thực hiện tất cả các việc này gây phức tạp một chút cho chương trình của bạn.
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 7 của 10
developerWorks®
ibm.com/developerWorks/vn/
Trong PHP V5.3, bộ gom rác sẽ dò tìm các quy chiếu vòng này và có thể giải phóng hết bộ nhớ
chúng sử dụng, do đó việc sử dụng bộ nhớ PHP sẽ giữ được ngang bằng khi kịch bản lệnh được
thực hiện. Khi mỗi tham chiếu đến lớp Parent được loại bỏ, tham chiếu lớp Child bên trong lớp
Parent cũng sẽ được gom rác.
Tóm tắt
PHP đã tiến thêm một quãng dài về cách hỗ trợ lập trình hướng đối tượng, từ việc hỗ trợ yếu trong
những ngày còn PHP V4 cho đến các bổ sung nhiều cải tiến hơn trong PHP V5 và các thay đổi
nhỏ với các bản tiếp sau đó. Hiện nay, PHP V5.3 đã đạt được một vài cải thiện hứng thú, gồm các
cải tiến về cú pháp như các phương thức ma thuật mới __callStatic(), các cuộc gọi tĩnh động,
liên kết tĩnh muộn, phương thức tĩnh, và trợ giúp thành viên. Các bổ sung mới vào SPL với các bổ
sung danh sách móc nối kép, các stack, heap, và hàng chờ, đặt ra một vài cấu trúc dữ liệu thông
thường trên đầu ngón tay bạn (dễ tìm thấy) và làm cho chúng dễ sử dụng. Cuối cùng, bộ gom rác
xoay vòng mong đợi từ lâu đã ổn định bộ nhớ và các vấn đề về hiệu năng làm việc với các lớp tự
quy chiếu, bằng cách cài đặt một bộ gom rác nhiều cải tiến mà đã giải phóng bộ nhớ đúng cách
cho các cá thể vòng tròn này. Tất cả các đặc tính này làm cho PHP V5.3 trở thành một ngôn ngữ
mạnh hơn nhiều đối với lập trình hướng đối tượng.
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 8 của 10
ibm.com/developerWorks/vn/
developerWorks®
Tài nguyên
Học tập
• Tiếp tục loạt bài này với "Có gì mới trong PHP V5.3, Phần 2, Phần 3 và Phần 4.
• Trang Zend Developer Zone có tư liệu dành cho các hàm quản lý bộ nhớ (memory manager
functions).
• Đọc "Một hướng dẫn về di trú PHP V5" để tìm hiểu cách di trú mã được phát triển trong PHP
từ bản V4 đến bản V5.
• "Kết nối các ứng dụng PHP với Apache Derby" chỉ cho bạn cách cài đặt và lập cấu hình PHP
trên Windows® (một vài bước có thể áp dụng với Linux®).
• PHP.net là tài nguyên trung tâm dành cho các nhà phát triển PHP.
• Xem trang "Danh sách các tài liệu PHP nên đọc."
• Duyệt qua toàn bộ nội dung PHP trên developerWorks.
• Mở rộng các kỹ năng PHP của bạn bằng cách xem trang Các tài nguyên dự án PHP của IBM
developerWorks.
• Lắng nghe các phỏng vấn và thảo luận thú vị cho các nhà phát triển phần mềm, xem trang
developerWorks podcasts.
• Sử dụng cơ sở dữ liệu với PHP? Hãy thử Zend Core for IBM, đó là một môi trường phát triển
và chạy sản xuất PHP liền khối, sẵn để dùng ngay, dễ dàng cài đặt và có hỗ trợ DB2 V9 của
IBM.
• Theo sát các sự kiện kỹ thuật và các buổi phát tin trên mạng.
• Theo dõi các hội nghị sắp được tổ chức, các triển lãm thương mại, các buổi phát thanh trên
mạng và các sự kiện khác trên khắp thế giới được các nhà phát triển mã nguồn mở của IBM
quan tâm.
• Truy cập trang Open source zone của developerWorks để có các thông tin về cách làm thế
nào, các công cụ, và cập nhật đối tượng sâu hơn để giúp bạn phát triển các công nghệ mã
nguồn mở và sử dụng chúng bằng các sản phẩm của IBM.
• Xem và tìm hiểu về IBM và các công nghệ mã nguồn mở và các chức năng của sản phẩm các
trình diễn miễn phí developerWorks Theo yêu cầu.
Lấy sản phẩm và công nghệ
• Đổi mới dự án phát triển mã nguồn mở tiếp theo của bạn bằng phần mềm chạy thử của IBM,
có sẵn để tải về hoặc trên DVD.
• Tải về các phiên bản chạy thử của sản phẩm IBM và bắt tay vào các công cụ phát triển
ứng dụng và các sản phẩm phần mềm trung gian DB2®, Lotus®, Rational®, Tivoli® và
WebSphere®.
Thảo luận
• Tham gia vào developerWorks blogs và vào cộng đồng developerWorks.
• Tham gia vào Hội thảo developerWorks PHP Forum: Phát triển các ứng dụng PHP với các
sản phẩm Quản trị Thông tin IBM (DB2, IDS).
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 9 của 10
developerWorks®
ibm.com/developerWorks/vn/
Đôi nét về tác giả
John Mertic
John Mertic đã tốt nghiệp đại học ngành Khoa học Máy tính của Đại học Quốc gia
Kent và hiện là kỹ sư phần mềm tại SugarCRM. Ông có nhiều đóng góp vào các dự án
mã nguồn mở, đáng kể nhất là các dự án PHP; ông là người tạo ra và duy trì Bộ Cài
đặt PHP trên Windows (PHP Windows Installer).
© Copyright IBM Corporation 2009
(www.ibm.com/legal/copytrade.shtml)
Nhẫn hiệu đăng ký
(www.ibm.com/developerworks/vn/ibm/trademarks/)
Có gì mới trong PHP 5.3, Phần 1: Các thay đổi về giao diện đối
tượng
Trang 10 của 10