看样子phar应该是山寨jar的吧,不过方便的确是方便许多。使用phar打包PHP代码的话,就可以直接在网上下载phar包,然后像这样直接运行他!
$ php foo.phar
我在本地自己做了个测试。建立了一个foo目录,目录里面有Foo.class.php和index.php两个文件:
<?php
// Foo.class.php
class Foo
{
public function __construct()
{
echo 'A Foo is created', PHP_EOL;
echo 'and the current dir is ', __DIR__;
}
}
<?php
// index.php
require __DIR__.'/Foo.class.php';
$foo = new Foo();
然后再写一个打包脚本来生成foo.phar文件:
<?php
// archive.php
// 要打包是需要在php.ini设置phar.readonly = off的,默认是on
$phar = new Phar('foo.phar', 0, 'foo.phar');
$phar->buildFromDirectory(__DIR__.'/foo');
执行
$ php archive.php
后当前目录下会多了一个foo.phar
文件,这个时候执行php foo.phar
,会发现跟执行php foo/index.php
差不多的效果。PHP会自动将index.php
作为phar包的bootstrap文件。
但是和直接执行foo/index.php
有所区别的是,直接执行__DIR__
显示的是/path/to/foo
而执行phar包显示的是phar:///path/to/foo.phar
,这说明执行phar包的时候PHP把.phar文件也当成一个目录,所以只要phar里面提到的文件路径都是用__DIR__
来获取的话,phar随便放什么路径都是可以正确执行而不会出现路径问题的。
另外我发现如果index.php
的require
路径不用__DIR__
常量而使用require './Foo.class.php'
,这样打包之后执行是会报错的,如果要做支持打包的程序,这点必须要注意。
对于打包大家应该都比较关心的问题是打包之后的性能问题。我在网上看到一个测试:http://marc.info/?l=php-internals&m=121394601217048&w=2,得出的结论是:打不打包对性能几乎没有任何的影响,无论你用不用APC什么的缓存技术。
下面再说说phar对于PHP程序设计的影响。我认为一个很大的影响是配置文件将更显现出他的重要地位。像PHP这种解释性的脚本语言,虽然我自己要设计程序的话配置文件我还是会习惯尽量和程序独立出来,但是我并不反对在某些逻辑代码里面直接写一些参数,只要能做到以后修改参数只用修改一处就行。我之所以这么认为是因为这本来就是解释性脚本语言相对于修改完一处代码就要重新编译的静态语言的一个大优点。不过phar这个东西相当于是个linker,刚才说的那个好处在使用phar之后就立马没有了,所以一个或者几个放在phar文件外面的配置文件就显得特别重要,特别是当你在代码里面使用Dependency Injection的时候,很有必要在phar外面放一个service container的描述文件来保持代码的灵活性。