How to work with zip archives in PHP. Today we will continue PHP lessons. I guess you noticed that due your project become larger – the more and more files it contain. Sometimes it comes to the thousands of files. And then – Phar can help you. This utility allows us to pack a variety of files in the single library file. Thus, we can significantly reduce the number of include files in the project, and work with the entire library as with single file. It is also possible to have a packed (gzip/bzip2) version of the library. These principles already using in other languages, such as a DLL library for system languages (as example .Net: N# and VB.Net) or JAR files for Java. Read more.
Phar extension appear in PHP since version 5.2. And since 5.3 – this is part of PHP core. Firstly I can suggest you to check version of your PHP. And if you have PHP 5.2 – you will need to re-build PHP core with Phar, zlib and bzip2 extensions. If you have 5.3 – just ignore, Phar already installed by default.
Make attention, by default, the PHAR archives have read-only access (so you will unable to create it). So, to have possibility to create own libraries (archives) you should to set phar.readonly = 0 in your php.ini and restart server.
In our lesson, I will tell you how you can create own libraries and use it. Here are samples and downloadable package:
[sociallocker]
download in package
[/sociallocker]
Ok, download the example files and lets start coding !
Step 1. PHP
Firstly, lets prepare 2 sample classes for us:
classes/SampleClass.php
<? class SampleClass { var $sName; var $sVersion; // constructor function SampleClass() { $this->sName = 'I am Sample class'; $this->sVersion = '1.0.0'; } function getAnyContent() { return '<h1>Hello World from Sample class</h1>'; } function getContent2() { return '<h2>Get content 2</h2>'; } } ?>
classes/SampleClass2.php
<? class SampleClass2 extends SampleClass { // constructor function SampleClass2() { $this->sName = 'I am Sample class 2'; $this->sVersion = '1.0.2'; } function getAnyContent() { return '<h1>Hello World from Sample class 2</h1>'; } } ?>
Very easy, isn`t it? And then, I`ll prepare single file (in same folder) which will load both classes:
classes/index.php
<? require_once('SampleClass.php'); require_once('SampleClass2.php'); ?>
My goal will wrap whole folder ‘classes’ into single library file.
Now, lets prepare ‘lib’ folder (with access to writing) in your root folder. And lets prepare our main PHP file which will able to compile our library, and it will contain demonstration that our library works well:
index.php
<? $sLibraryPath = 'lib/SampleLibrary.phar'; // we will build library in case if it not exist if (! file_exists($sLibraryPath)) { ini_set("phar.readonly", 0); // Could be done in php.ini $oPhar = new Phar($sLibraryPath); // creating new Phar $oPhar->setDefaultStub('index.php', 'classes/index.php'); // pointing main file which require all classes $oPhar->buildFromDirectory('classes/'); // creating our library using whole directory $oPhar->compress(Phar::GZ); // plus - compressing it into gzip } // when library already compiled - we will using it require_once('phar://'.$sLibraryPath.'.gz'); // demonstration of work $oClass1 = new SampleClass(); echo $oClass1->getAnyContent(); echo '<pre>'; print_r($oClass1); echo '</pre>'; $oClass2 = new SampleClass2(); echo $oClass2->getAnyContent(); echo $oClass2->getContent2(); echo '<pre>'; print_r($oClass2); echo '</pre>'; ?>
Here you can see result of our page:
In beginning, I check, are compiled library (lib/SampleLibrary.phar) already exists or not. If exist – I don`t will compile it again, but if not exist – we will automatically compile (and pack) our library. Firstly lets check ‘readonly’ variable into Off state (or using php.ini or via ini_set function). Then, in constructor of Phar – pass name of our future library. After, I using ‘setDefaultStub’ function to make some auto-execute file which will executing when we including our library. In Phar extension it called ‘stab’. After, via ‘buildFromDirectory’ function I compiling our phar file into library, and via ‘compress’ function – pack it into gzip (SampleLibrary.phar.gz) version. Accessing to our classes will direct, without necessarity to extract our library (all via PHP Stream Wrapper).
You can use different ways (functions) to add files into library, this is possible via:
- via object properties
- Phar::addFile()
- Phar::addFromString()
- Phar::addEmptyDir()
- Phar::buildFromDirectory()
- Phar::buildFromIterator()
Ok, in first half or this file we created our library, then, we will use it, we will use ordinary ‘require_once’ function to include our result library (GZipped). Make attention to ‘phar://’, we should point that we going to attach Phar file (PHAR stream wrapper).
Conclusion
In result, want to tell that here are several advantages of using Phar: its easy to use, you can pack multiple resource-files in single library, and, it have good performance. If you have any suggestions, or you just have to say – we are glad to hear it. Good luck in your projects!
Why are you using php4 oop code?
The example code doesn’t make much sense.
You should have just created a phar file and then demonstrate how to use the code that’s in the phar file.
Not show code to check if there is a phar file, create if it doesn’t exist and then call the classes etc.. Who in their right mind would do such a thing?
This code show us 2 things – creating phar file itself (auto-building) and using of already exist phar file.
You always can separate it to different files. In one place – perform compilation of library, and in second (main project) – using of this library.
You’ve made an mistake in your code!
The second codesnippet belongs to file classes/SampleClass2.php and not classes/SampleClass.php
2 ragtek
Yes, thanks my friend for correction. This is good that you was able to notice it :)
Hello admin,
you say a phar file has better performance compared to single files. Do you have a benchmark (if possible with and without a ByteCode-Cache) to proove that statement?
2 PHPGangsta
Hi, as I read in documentation:
So, can hope that it will faster in practice too. I don`t made benchmarks yet. But can if this is really interesting :)