Có gì mới trong PHP 5.3, Phần 4: Tạo và Sử dụng các tệp nén Phar

PHP V5.3 được lên lịch để phát hành sớm. Loạt bài "Có gì mới trong PHP V5.3" này bao hàm các tính năng mới và hấp dẫn trong bản phát hành này. Phần 1 xem xét các thay đổi về lập trình hướng đối tượng và xử lý đối tượng trong PHP V5.3, Phần 2 xem xét các hàm lambda và bao đóng. Và trong Phần 3, chúng ta đã xem xét các không gian tên, là một trong các tính năng được đoán trước nhiều nhất và gây tranh cãi nhất trong bản phát hành này của PHP. Trong Phần 4 sau đây, chúng ta sẽ xem xét kỹ hơn về Phar, một định dạng tệp nén có thể sử dụng được trong PHP. Nó có thể sử dụng không những để lưu trữ các tệp mà còn để đưa vào và chạy toàn bộ một ứng dụng PHP từ một tệp duy nhất. Nó có thể được sử dụng với PHP như một phần mở rộng từ kho chứa PECL, nhưng sẽ là một phần mở rộng chính thức của PHP trong phiên bản V5.3 này.

John Mertic, Kỹ sư phần mềm, SugarCRM

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).



27 01 2009

Khái niệm về các tệp nén Phar đến từ các tệp nén JAR của công nghệ Java™ nó cho phép bạn gói một ứng dụng vào một tệp đơn lẻ chứa mọi thứ cần thiết để chạy ứng dụng. Nó khác với khái niệm của một tệp trực khai duy nhất, được tạo ra bình thường bằng các ngôn ngữ, chẳng hạn như C, do tệp thật sự là một nơi lưu trữ và không phải là một tệp ứng dụng. Như vậy tệp JAR thực ra là chứa các tệp làm nên ứng dụng, mặc dù chúng có thể bị che giấu vì lý do an toàn. Phần mở rộng của Phar dựa trên một khái niệm tương tự, nhưng nó được thiết kế nhiều hơn cho môi trường web của PHP. Ngoài ra, không như các tệp nén JAR, các tệp nén Phar có thể được xử lý bằng chính PHP và không đòi hỏi có một công cụ bên ngoài nào để tạo ra hoặc sử dụng chúng.

Phần mở rộng Phar hoàn toàn không mới đối với PHP. Ban đầu nó được viết bằng PHP và gọi là tệp nén PHP (PHP Archive), và nó đã được thêm vào thư mục PEAR vào năm 2005. Tuy nhiên, một giải pháp thuần PHP về vấn đề này khá chậm trễ trong thế giới thực, nên nó đã được viết lại như một phần mở rộng thuần C vào năm 2007, đồng thời việc hỗ trợ đã được bổ sung để sử dụng đối tượng ArrayAccess của SPL để lặp lại qua một tệp nén Phar. Từ đó, đã có khá nhiều việc đã được thực hiện để cải thiện hiệu năng của các tệp nén Phar.

Tạo một Phar

Có một số bước cần thiết để tạo ra một tệp Phar. Tất cả các bước đòi hỏi các lệnh PHP trong một số dạng để làm điều này, do không tồn tại các công cụ độc lập để tạo ra các tệp nén này. Ngoài ra, để tạo ra và sửa đổi tệp Phar, thiết lập php.ini và phar.readonly phải đặt ở 0. Thiết lập này không đòi hỏi phải mở hoặc tham chiếu tệp trong một tệp nén Phar trong PHP.

Chúng ta hãy xem xét các bước cần để tạo ra một tệp nén Phar mà có thể dùng để điều khiển một ứng dụng. Ứng dụng này sẽ được thiết kế để nạp trực tiếp từ trình duyệt web hoặc dấu nhắc lệnh. Bước đầu tiên là tạo tệp Phar, như vậy chúng ta sẽ làm điều này bằng cách tạo ra đối tượng Phar mà chúng ta sẽ làm việc với thí dụ này trong Liệt kê 1. Điểm tham chiếu đối tượng sẽ cho phép bạn điều khiển tất cả các khía cạnh của tệp nén Phar.

Liệt kê 1. Tạo đối tượng Phar
$p = new Phar('/path/to/my.phar', CURRENT_AS_FILEINFO | KEY_AS_FILENAME, 'my.phar');
$p->startBuffering();

Tham số thứ nhất cho hàm dựng là đường dẫn đến nơi tệp Phar sẽ được lưu. Tham số thứ hai chuyển bất kỳ tham số nào đến lớp cha RecursiveDirectoryIterator. Tham số thứ ba là các bí danh dùng cho cách tệp nén Phar được tham chiếu đến trong ngữ cảnh các luồng (streams context). Như vậy đối với Liệt kê 1, bạn có thể tham chiếu đến một tệp trong Phar này là phar://my.phar. Bạn cũng có thể chạy phương thức gọi Phar::startBuffering() để làm vật đệm cho các thay đổi đến tệp nén cho đến khi bạn chạy lệnh Phar::stopBuffering(). Mặc dù không cần thiết phải làm điều này, nó vẫn cải thiện được hiệu năng của việc tạo ra hoặc sửa đổi một tệp nén do nó tránh được sự cần thiết phải lưu các thay đổi đến tệp nén mỗi khi nó được thay đổi trong kịch bản lệnh của bạn.

Theo mặc định, Phar tạo ra sẽ sử dụng định dạng tệp nén dựa trên Phar tự nhiên (native Phar-based archive format). Bạn cũng có thể sử dụng định dạng ZIP hoặc TAR cho tệp Phar bằng cách chuyển đổi nó sang định dạng đó, như thể hiện trong Liệt kê 2, bằng cách thay đổi định dạng sang ZIP.

Liệt kê 2. Thay đổi định dạng lưu trữ sang ZIP
$p = $p->convertToExecutable(Phar::ZIP);

Có các ưu, nhược điểm khi thay đổi định dạng tệp nén. Ưu điểm chính là khả năng kiểm tra nội dung của tệp nén bằng bất kỳ công cụ nào để xử lý các tệp ZIP hoặc TAR. Tuy nhiên, với sử dụng một tệp nén Phar mà không dùng định dạng tệp nén dựa trên Phar tự nhiên không đòi hỏi phải sử dụng phần mở rộng Phar để tải tệp nén, trong khi các tệp nén có định dạng ZIP hoặc TAR lại cần đến.

Tiếp theo, bạn sẽ cần phải xác định tệp stub, nó là mã thứ nhất được gọi khi tệp Phar được nạp.


Tệp Phar stub

Tệp stub chỉ là một đoạn nhỏ của mã chạy lúc đầu khi tệp Phar được nạp, và nó luôn luôn kết thúc bằng một dấu hiệu __HALT_COMPILER(). Liệt kê 3 thể hiện một tệp stub thường sẽ trông như thế nào.

LLiệt kê 3. Tệp Phar stub
<?php
Phar::mapPhar();
include 'phar://myphar.phar/index.php';
__HALT_COMPILER();

Phương thức gọi Phar::mapPhar() chỉ ra trên đây khởi động tệp nén Phar bằng cách đọc bảng kê (manifest). Bạn cần phải làm việc này trước khi tham chiếu các tệp trong tệp nén bằng cách sử dụng phar://stream wrapper. Tệp để nạp lúc đầu sẽ là cái mà tệp ứng dụng của bạn sẽ bình thường nạp đầu tiên; với thí dụ này là index.php.

Cách thức thêm tệp stub này vào tệp nén Phar của bạn tuỳ thuộc vào định dạng nén nào bạn đang sử dụng. Đối với các tệp nén dựa trên Phar, sử dụng phương thức Phar::setStub() nó chấp nhận tham số duy nhất của mã PHP để đưa vào stub như một chuỗi. Liệt kê 4 minh hoạ cách tiếp cận này.

Liệt kê 4. Sử dụng Phar::setStub() để tạo tệp stub
$p->setStub('<?php Phar::mapPhar(); 
include 'phar://myphar.phar/index.php'; __HALT_COMPILER(); ?>');

Nếu bạn không lên kế hoạch về làm việc nhiều với stub trừ việc đổi hướng một trang index.php, có thể sử dụng phương thức trợ giúp Phar::createDefaultStub() để xây dựng tệp stub cho bạn. Đối với việc này, bạn sẽ chỉ cần chuyển tên tệp mà bạn muốn gộp vào tệp stub. Trong Liệt kê 5, bạn sẽ viết lại phương thức gọi Phar::setStub() để sử dụng phương thức trợ giúp này.

Liệt kê 5. Sử dụng Phar::createDefaultStub() để tạo ra tệp stub
$p->setStub($p-> createDefaultStub('index.php'));

Một đối số tuỳ chọn thứ hai cho phương thức Phar::createDefaultStub() cho phép bạn gộp một tệp khác nếu Phar được nạp từ một máy chủ web. Việc này thật tiện lợi trong trường hợp ứng dụng của bạn được thiết kế để sử dụng trong một dòng lệnh và một ngữ cảnh trình duyệt web.

Đối với các cài đặt dựa trên ZIP và TAR, bạn lưu lại các nội dung của stub trên đây vào tệp .phar/stub.php, thay cho việc sử dụng lệnh setStub().


Thêm các tệp vào archive

Đối tượng Phar sử dụng đối tượng SPL ArrayAccess để cho phép truy cập các nội dung của tệp nén như là một mảng, cho nên nó mở ra nhiều cách thêm các tệp vào tệp nén. Cách dễ nhất là sử dụng giao diện ArrayAccess trực tiếp.

Liệt kê 6. Thêm tệp vào một tệp nén
$p['file.txt'] = 'This is a text file';
$p['index.php'] = file_get_contents('index.php');

Liệt kê 6 cho thấy tên tệp được xác định làm khoá mảng và các nội dung là giá trị. Bạn có thể sử dụng hàm file_get_contents() để lấy các nội dung của một tệp hiện hành để thiết lập làm các giá trị. Việc này đảm bảo linh hoạt một chút về cách thêm một tệp vào một tệp nén, bằng cách hoặc tham chiếu một tệp hiện hành hoặc xây dựng một tệp đang chạy. Cách xây dựng tệp là hữu ích khi một bộ phận của một ứng dụng xây dựng kịch bản lệnh.

Nếu tệp bạn đang lưu trong tệp nén Phar là lớn, bạn có thể tuỳ ý nén tệp trong tệp nén bằng cách sử dụng cách nén gzip hoặc bzip2 qua phương thức PharFileInfo::setCompressedGZ() hoặc PharFileInfo::setCompressedBZIP2() tương ứng. Trong Liệt kê 7, bạn sẽ nén một tệp bằng cách sử dụng bzip2.

Liệt kê 7. Nén một tệp trong một tệp nén Phar bằng cách sử dụng bzip2
$p['big.txt'] = 'This is a big text file';
$p['big.txt']->setCompressedBZIP2();

Để nén tệp hoặc sử dụng một tệp nén với tệp được nén trong nó, bzip2 hoặc zlib (đối với các tệp nén gz) phần mở rộng phải được kích hoạt trong phần cài đặt PHP.

Giả thiết rằng bạn có nhiều tệp để thêm vào một tệp nén. Việc thêm vào chúng từng tệp một nhờ giao diện ArrayAccess có thể là đơn điệu, cho nên có vài phím tắt cho việc này. Một cách là sử dụng phương thức Phar::buildFromDirectory(), nó sẽ đi qua một thư mục riêng và thêm các tệp vào nó. Nó cũng hỗ trợ việc lọc các tệp để thêm bằng cách chuyển qua một tham số thứ hai với mẫu biểu thức chính qui của các tệp để khớp và thêm vào tệp nén. Liệt kê 8 cho biết cách sử dụng.

Liệt kê 8. Thêm tệp vào một tệp nén bằng cách sử dụng Phar::buildFromDirectory()
$p->buildFromDirectory('/path/to/files','./\.php$/');

Liệt kê 8 thêm tất cả các tệp PHP trong thư mục đã định vào tệp nén Phar. Bạn sau đó có thể quay trở lại bằng cách sử dụng giao diện ArrayAccess nếu bạn cần thực hiện bất kỳ thay đổi nào đến tệp được thêm vào, chẳng hạn như thiết lập chúng để nén.

Bạn cũng có thể sử dụng phương thức Phar::buildFromIterator() để thêm tệp bằng cách sử dụng một biến lặp. Hai loại biến lặp được hỗ trợ: biến lặp cho phép khớp tên tệp trong Phar với tên của tệp trên đĩa và biến lặp trả lại các đối tượng SplFileInfo. Một biến lặp tương thích như vậy là RecursiveDirectoryIterator, nó được sử dụng dưới đây để thêm các tệp trong một thư mục vào tệp nén.

Liệt kê 9. Thêm các tệp vào một tệp nén bằng cách sử dụng Phar::buildFromIterator()
$p->buildFromIterator(new RecursiveIteratorIterator
(new RecursiveDirectoryIterator('/path/to/files')),'/path/to/files');

Phương thức Phar::buildFromIterator() chấp nhận đối tượng biến lặp tự nó như là đối số duy nhất. Trong thí dụ trên, bạn đã bọc đối tượng RecursiveDirectoryIterator bằng đối tượng RecursiveIteratorIterator, đối tượng sau cung cấp kiểu biến lặp tương thích mà phương thức Phar::buildFromIterator() cần đến.

Chúng ta bây giờ đã tạo ra một tệp nén Phar, nó có thể được sử dụng bằng bất kỳ ứng dụng PHP nào. Chúng ta hãy xem bạn có thể sử dụng này tệp nén này dễ như thế nào.


Xử lý tệp nén Phar

Phần hấp dẫn về tệp nén Phar là chúng dễ dàng hợp nhất vào bất kỳ ứng dụng nào. Điều này đặc biệt đúng nếu bạn đã sử dụng định dạng tệp nén dựa vào Phar nguyên bản. Trong trường hợp này, bạn thậm chí không cần phần mở rộng của Phar đã cài đặt, do PHP có thể nạp từ đầu tệp đó và trích xuất nội dung của nó. Các tệp nén dựa trên ZIP và TAR đòi hỏi có phần mở rộng Phar được nạp.

Tệp nén Phar được thiết kế để chứa trong một ứng dụng, giống như bất kỳ tệp PHP bình thường nào, cho phép sử dụng tệp tư liệu Phar rất dễ dàng cho người phát triển ứng dụng đã sẵn sàng quen với việc gộp mã của bên thứ ba. Chúng ta hãy xem cách nó dễ dàng hợp nhất một Phar vào ứng dụng của bạn.


Tích hợp mã tư liệu tệp nén Phar vào ứng dụng của bạn

Cách dễ nhất để tích hợp mã trong một tệp nén Phar chỉ là bằng cách gộp vào tệp nén Phar, sau đó gộp vào tệp trong tệp Phar bạn muốn sử dụng. Trình bao bọc phar://stream có thể được sử dụng để truy cập một tệp bên trong một tệp nén Phar được nạp, như dưới đây.

Liệt kê 10. Nạp bộ mã trong một tệp nén Phar
include 'myphar.phar';  
include 'phar://myphar.phar/file.php';

Dòng thứ nhất sẽ nạp tệp nén myphar.phar, gồm cả mã được xác định trong tệp stub. Dòng thứ hai sử dụng trình bao bọc luồng để mở tệp nén Phar và chỉ gộp vào tệp đã xác định bên trong tệp nén. Lưu ý rằng bạn không cần phải gộp chính tệp nén Phar trước khi gộp vào một tệp bên trong tệp nén, như trong Liệt kê 10.


Chạy một ứng dụng PHP từ một tệp nén Phar

Một điều rõ ràng mà bạn có thể thực hiện với tệp nén Phar là bó toàn bộ ứng dụng bằng một tệp nén Phar và cấp phát nó theo cách đó. Ưu điểm của cách tiếp cận này là ở chỗ nó làm dễ dàng triển khai ứng dụng và không bị giảm hiệu năng, nhờ một số nâng cao cho Phar trong bản PHP V5.3. Tuy nhiên, khi thiết kế một ứng dụng để chạy bên trong một Phar, sau đây là một vài ý kiến nhận xét với thiết kế của ứng dụng mà bạn nên nắm rõ:

  1. Bất kỳ tệp nào cần tạo mà là riêng cho một thể hiện của ứng dụng, chẳng hạn như tệp cấu hình config, không thể là một bộ phận của tệp nén, như vậy bạn sẽ cần ghi chúng vào một vị trí riêng nhưng có thể truy cập được.Cùng một cách như thế nếu ứng dụng của bạn tạo ra bất kỳ tệp cache nào như một phần trực khai.
  2. Bạn phải giữ nguyên định dạng tệp nén dựa trên Phar mà không nén các tệp trong tệp nén để gọn nhẹ nhất. Các tệp nén dựa trên ZIP và TAR đòi hỏi phần mở rộng Phar phải cài đặt trong PHP, trong khi các tệp dựa trên Phar có thể sử dụng được kể cả khi không cài đặt phần mở rộng Phar.
  3. Bất kỳ tham chiếu nào đến các tệp trong ứng dụng cần được thay đổi để sử dụng trình bao bọc phar://stream với tên của tệp nén, như đã chỉ ra trong phần trước.

PHPMyAdmin là một ứng dụng PHP phổ biến, được đóng gói trong Phar để sử dụng như là một ví dụ về cách sử dụng dễ dàng tệp nén Phar (xem Tài nguyên). Nó đã được thiết kế tổng thể để chạy từ tệp nén Phar, nhưng vẫn cung cấp khả năng lưu lại tệp cấu hình của nó bên ngoài tệp nén Phar.


Tóm tắt

Các tệp nén Phar là một bổ sung khá tiện lợi vào bản PHP V5.3. Chúng cung cấp khả năng đóng gói bộ mã PHP trong một tệp nén, có thể rất hữu ích để phân bố một ứng dụng hoặc thư viện chỉ trong một tệp. Tệp nén Phar có thể nạp dễ dàng từ một tệp PHP bằng cách sử dụng hàm yêu cầu hoặc hàm chứa, hoặc có thể được thực hiện trực tiếp từ trình duyệt hoặc dòng lệnh bằng cách xác định tên tệp nén Phar.

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

  • PHPMyAdmin là một ứng dụng PHP phổ biến mà đã được gói trong Phar để sử dụng như là một ví dụ về việc sử dụng dễ dàng tệp nén Phar.
  • Nhận sản phẩm PHP V5.2.6.
  • Đổ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 trung gian từ DB2®, Lotus®, Rational®, Tivoli® và WebSphere®.

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=444968
ArticleTitle=Có gì mới trong PHP 5.3, Phần 4: Tạo và Sử dụng các tệp nén Phar
publish-date=01272009