PHP extension-compression and archive extension-the Phar archive concept comes from the JAR archive of Java technology, which allows the use of a single file to package applications, this file contains everything required to run the application. This file is different from a single executable file, which is usually generated by a programming language, such as C, because the file is actually an archive file rather than a compiled application. Therefore, the JAR file actually contains the files that constitute the application, but these files are not carefully distinguished for security purposes. Phar extensions are based on similar concepts, but are designed primarily for PHP Web environments. Similarly, unlike JAR archiving, Phar archiving can be processed by PHP itself, so no additional tools are required for creation or use.
Phar extension is not a new concept for PHP. It was originally written in PHP and named PHP_Archive. it was added to the PEAR Library in 2005. However, in practice, the pure PHP solution to this problem is very slow. Therefore, in 2007, it was rewritten as a pure C language extension, added support for traversing Phar archives using ArrayAccess objects of SPL. Since then, people have done a lot of work to improve the performance of Phar archiving.
Create Phar
Several steps are required to create a Phar file. All steps require some form of PHP command to complete the creation, because there is no independent tool for creating an archive. To create and modify a Phar file, set phar. readonly to 0 in php. ini. You do not need to use this setting when opening or referencing a file in the PHP Phar archive.
Let's take a look at the steps required to create a Phar file that can be used to drive the application. The application is designed to load directly from a Web browser or command prompt. The first step is to create the Phar file, so we will create the Phar object shown in listing 1. Object reference allows you to control all aspects of Phar archiving.
Example 1. create a Phar object
$p = new Phar('/path/to/my.phar', CURRENT_AS_FILEINFO | KEY_AS_FILENAME, 'my.phar');$p->startBuffering();
The first parameter of the constructor indicates the location where the Phar file is saved. The second parameter passes all parameters to the RecursiveDirectoryIterator parent class. The third parameter references the Phar archive alias in the stream context. Therefore, for listing 1, you can use Phar: // my. phar to reference the file in this phar archive. You can also call the Phar: startBuffering () method to buffer the changes made to the archive until the Phar: stopBuffering () command is issued. Although you do not have to perform the above operations, this does improve the performance of creating or modifying the archive, because it avoids saving the modifications made every time you modify the archive in the script.
By default, the created Phar uses the native Phar-based archive format. You can also convert the format to the ZIP format as shown in listing 2 to use the ZIP or TAR format for the Phar file.
Example 2. convert the storage format to ZIP format
$p = $p->convertToExecutable(Phar::ZIP);
Conversion of archive formats also has advantages and disadvantages. The main advantage is that you can use any tool to process ZIP or TAR files to view the archived content. However, if the Phar archive does not use the native Phar-based archive format, it does not need to use the Phar extension to load the archive, but it is required to use the Phar archive in ZIP or TAR format.
Next, you need to define the file stub (stub), which is the first code called when loading the Phar file.
Phar file stubs
The file stub is only a small part of the code initially run when the Phar file is loaded, and always ends with a _ HALT_COMPILER () mark. Listing 3 shows a typical file stub.
Example 3. Phar file stub
The preceding Phar: mapPhar () method is called to initialize the Phar archive by reading the manifest file. You must use the phar: // stream package to perform initialization before referencing a file in the archive. The initial file is the file when the application loads it for the first time. In this example, it is index. php.
How to add the file stub Phar to the Phar archive depends on the archive format used. For Phar-based archiving, use the Phar: setStub () method, which accepts the unique parameters of the PHP code and puts them in the stub as strings. Listing 4 demonstrates this method.
Example 4. use Phar: setStub () to create a file stub
$p->setStub('
');
If you plan to use a stub instead of redirecting to the index. php page to complete the operation, you can use the helper method Phar: createdefadefastub () to build the file stub. Therefore, you only need to pass the name of the file that you want to include in the file stub. In listing 5, you will override the Phar: setStub () method call to use the helper method.
Example 5. use Phar: createDefaultStub () to create a file stub
$p->setStub($p-> createDefaultStub('index.php'));
If you load the Phar, Phar: createdefastustub () method from the Web server, the Second Optional parameter can contain a different file. This is very convenient for applications designed for command line or Web browser context.
For the implementation based on ZIP and TAR, store the content of the above stubs in the. phar/stub. php file instead of using the setStub () command.
Add an object to an archive
The Phar object uses the ArrayAccess SPL object to allow access to the archive content in the form of arrays. Therefore, many methods are provided to add files to the archive. The simplest method is to directly use the ArrayAccess interface.
Example 6. add an object to the archive
$p['file.txt'] = 'This is a text file';$p['index.php'] = file_get_contents('index.php');
Example 6 indicates that the file name is specified as an array key and the content is specified as a value. You can use the file_get_contents () function to obtain the content of an existing file and set the content to a value. In this way, you can add files to the archive more flexibly by referencing existing files or dynamically building files. The latter method can be used as part of the application build script.
If the files stored in the Phar archive are very large, you can use the PharFileInfo: setCompressedGZ () or PharFileInfo: setCompressedBZIP2 () method to selectively compress the files in the archive using gzip or bzip2 compression. In listing 7, you will use bzip2 to compress the file.
Example 7. use bzip2 to compress files in the Phar Archive
$p['big.txt'] = 'This is a big text file';$p['big.txt']->setCompressedBZIP2();
To compress files or archive files that contain them, you must support bzip2 or zlib (for gz compressed files) extensions in PHP installation.
Assume that you need to add many files to the archive. Using the ArrayAccess interface to add files one by one is a very monotonous task, so you can use some convenient methods. One method is to use the Phar: buildFromDirectory () method, which traverses the specified directory and adds the files to it. It also supports filtering the added files by passing the second parameter in the regular expression mode of the file to match the file and add it to the archive. Listing 8 shows the process.
Example 8. use Phar: buildFromDirectory () to add a file to the archive
$p->buildFromDirectory('/path/to/files','./\.php$/');
Example 8: add the PHP file in the specified directory to the Phar archive. If you want to perform any modification to the added file, such as compressing the file, you can use the ArrayAccess interface to return the modification.
You can use an iterator to add files through the Phar: buildFromIterator () method. Two types of iterators are supported: one is to map the file name in Phar to the name of the disk file, and the other is to return the SplFileInfo object. RecursiveDirectoryIterator is a compatible iterator. the following shows how to use it to add directory files to the archive.
Example 9. use Phar: buildFromIterator () to add a directory file to the archive
$p->buildFromIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/path/to/files')),'/path/to/files');
Phar: The buildFromIterator () method accepts the iterator object as the only parameter. In the preceding example, you have used the RecursiveIteratorIterator object to wrap the RecursiveDirectoryIterator object. the RecursiveIteratorIterator object provides the compatible iterator required by the Phar: buildFromIterator () method.
We have now created a Phar archive for any PHP application. Let's take a look at how to easily use this archive.
Archive with Phar
One advantage of Phar archiving is that it can be easily integrated into any application. This is especially evident if the native Phar-based archive format is used. In this case, you do not even need to install the Phar extension, because PHP is born to be able to load files and extract file content. Phar extensions must be loaded for ZIP and TAR-based archives.
Phar archives are included in applications during design, just like common PHP files, this allows application developers familiar with how to include other third-party code to easily use Phar archiving. Let's take a look at how easy it is to integrate Phar in an application.
Integrate Phar archive code in applications
The simplest way to integrate code in Phar archive is to include Phar archive and then include the files to be used in Phar files. Phar: // The Stream wrapper can be used to access files in the attached Phar archive, as shown below.
Example 10. load the code in the Phar Archive
include 'myphar.phar'; include 'phar://myphar.phar/file.php';
The first include will load the myphar. phar archive, containing the code specified in the file stub. The second include uses the stream package to open the Phar archive and only includes the specified file in the archive. Note that you do not need to include the Phar archive, as shown in listing 10.
Run PHP applications from Phar Archives
An outstanding feature of Phar archiving is that you can use a Phar archive to package and release the entire application. The advantage of this method is that it simplifies application deployment and does not reduce performance. it is mainly benefited from several new Phar enhancements in PHP V5.3. However, the following points should be taken into account when designing an application running in Phar:
Any files that need to be created that are specific to the application instance, such as the config file, cannot be part of the archive. Therefore, you need to write them to an independent but accessible location. If an application creates an extended cache file, the same procedure should be used for these files.
You should always use the Phar-based archive format and do not compress the files in the archive for maximum flexibility. Phar extensions must be installed in PHP based on ZIP and TAR archives. Phar-based archives can even be used without Phar extensions.
Any file reference in the application must be modified to use the phar: // stream package and archive name at the same time, as shown in the previous section.
PHPMyAdmin is a popular PHP application that uses Phar packaging to demonstrate the simplicity of Phar archiving. It has been designed to run from the Phar archive file, but it can still store configuration files outside the Phar archive.