PHP中phar(PHP Archive)包的创建并使用
2017-01-19
2024
一:phar包介绍
1)至php5.3起,php便支持了类似Java的jar包,名为phar(PHP Archive)。用来将多个PHP文件打包为一个文件,即可以将整个目录下的文件打包成单个可执行文件。虽然单个PHP文件也是可执行(Composer的install就是单个PHP文件执行创建对应的Phar),但是显得不方便。
2)官网介绍:
PHP
The phar extension provides a way to put entire PHP applications into a single file
called a "phar" (PHP Archive) for easy distribution and installation.
1
2
ThepharextensionprovidesawaytoputentirePHPapplicationsintoasinglefile
calleda"phar"(PHPArchive)foreasydistributionandinstallation.
3)使用phar可以很方便的打包你的代码,集成部署到线上机器。此外,如果你运行在5.5以上的版本(默认打开opcache),几乎对性能没有影响。
二:创建并使用Phar
创建 Phar 文件需要执行若干步骤。所有步骤需要用到某种形式的 PHP 命令完成创建,因为不存在用于创建归档的独立工具。
1)php.ini修改
创建Phar需要更改php.ini如下:
PHP
;phar.readonly = On
phar.readonly = Off
1
2
;phar.readonly=On
phar.readonly=Off
2)使用phar demo目录结构:
Shell
drwxr-xr-x. 1 www www 102 1月 19 11:06 app
-rw-r--r--. 1 www www 850 1月 19 11:06 build.php
-rw-r--r--. 1 www www 110 1月 19 11:06 index.php
drwxr-xr-x. 1 www www 102 1月 19 11:06 lib
1
2
3
4
drwxr-xr-x.1wwwwww1021月1911:06app
-rw-r--r--.1wwwwww8501月1911:06build.php
-rw-r--r--.1wwwwww1101月1911:06index.php
drwxr-xr-x.1wwwwww1021月1911:06lib
Shell
[root@bogon phar-sample]# cd app
[root@bogon app]# ll
总用量 4
-rw-r--r--. 1 www www 120 1月 19 11:06 HelloWorld.php
1
2
3
4
[root@bogonphar-sample]# cd app
[root@bogonapp]# ll
总用量4
-rw-r--r--.1wwwwww1201月1911:06HelloWorld.php
Shell
[root@bogon phar-sample]# cd lib/
[root@bogon lib]# ll
总用量 4
-rw-r--r--. 1 www www 23 1月 19 11:06 MyLib.php
1
2
3
4
[root@bogonphar-sample]# cd lib/
[root@bogonlib]# ll
总用量4
-rw-r--r--.1wwwwww231月1911:06MyLib.php
3) application文件
PHP
[root@bogon phar-sample]# cat index.php
require __DIR__ . '/lib/MyLib.php';
require __DIR__ . '/app/HelloWorld.php';
new HelloWorld();
1
2
3
4
5
6
7
[root@bogonphar-sample]# cat index.php
require__DIR__.'/lib/MyLib.php';
require__DIR__.'/app/HelloWorld.php';
newHelloWorld();
Shell
[root@bogon phar-sample]# cd app/
[root@bogon app]# cat HelloWorld.php
class HelloWorld extends MyLib
{
public function __construct()
{
echo "Hello World!\n";
}
}
1
2
3
4
5
6
7
8
9
10
11
[root@bogonphar-sample]# cd app/
[root@bogonapp]# cat HelloWorld.php
classHelloWorldextendsMyLib
{
publicfunction__construct()
{
echo"Hello World!\n";
}
}
Shell
[root@bogon phar-sample]# cat lib/MyLib.php
class MyLib
{}
1
2
3
4
5
[root@bogonphar-sample]# cat lib/MyLib.php
classMyLib
{}
4)先测试下执行index.php文件能否正常使用:
Shell
[root@bogon phar-sample]# php index.php
Hello World!
1
2
[root@bogonphar-sample]# php index.php
HelloWorld!
5)创建build.php文件,真正phar打包在此文件
PHP
$dir = __DIR__; // 需要打包的目录
$file = 'test.phar'; // 包的名称, 注意它不仅仅是一个文件名, 在stub中也会作为入口前缀
$phar = new Phar(__DIR__ . '/' . $file, FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME, $file);
//开始打包
$phar->startBuffering();//缓冲对归档做出的修改
$phar->buildFromDirectory($dir);//遍历指定的目录并把其中的文件加入到归档中
$phar->delete('build.php');//把build.php本身摘除
//设置入口,定义文件存根(stub)
$phar->setStub("<?php
Phar::mapPhar('{$file}');
require 'phar://{$file}/index.php';
__HALT_COMPILER();
?>");
//停止缓冲,尽管不一定要执行上述操作,这样做可以改善创建或修改归档的性能,因为它避免了每次在脚本中修改归档时对做出的修改进行保存。
$phar->stopBuffering();
// 打包完成
echo "Finished {$file}\n";
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$dir=__DIR__;// 需要打包的目录
$file='test.phar';// 包的名称, 注意它不仅仅是一个文件名, 在stub中也会作为入口前缀
$phar=newPhar(__DIR__.'/'.$file,FilesystemIterator::CURRENT_AS_FILEINFO|FilesystemIterator::KEY_AS_FILENAME,$file);
//开始打包
$phar->startBuffering();//缓冲对归档做出的修改
$phar->buildFromDirectory($dir);//遍历指定的目录并把其中的文件加入到归档中
$phar->delete('build.php');//把build.php本身摘除
//设置入口,定义文件存根(stub)
$phar->setStub("<?php
Phar::mapPhar('{$file}');
require'phar://{$file}/index.php';
__HALT_COMPILER();
?>");
//停止缓冲,尽管不一定要执行上述操作,这样做可以改善创建或修改归档的性能,因为它避免了每次在脚本中修改归档时对做出的修改进行保存。
$phar->stopBuffering();
// 打包完成
echo "Finished{$file}\n";
6)进行打包
Shell
[root@bogon phar-sample]# php build.php
Finished test.phar
//打包成test.phar文件
[root@bogon phar-sample]# ll
总用量 32
drwxr-xr-x. 1 www www 102 1月 19 11:06 app
-rw-r--r--. 1 www www 598 1月 19 11:23 build.php
-rw-r--r--. 1 www www 104 1月 19 11:10 index.php
drwxr-xr-x. 1 www www 102 1月 19 11:06 lib
-rw-r--r--. 1 www www 22855 1月 19 11:25 test.phar
1
2
3
4
5
6
7
8
9
10
11
[root@bogonphar-sample]# php build.php
Finishedtest.phar
//打包成test.phar文件
[root@bogonphar-sample]# ll
总用量32
drwxr-xr-x.1wwwwww1021月1911:06app
-rw-r--r--.1wwwwww5981月1911:23build.php
-rw-r--r--.1wwwwww1041月1911:10index.php
drwxr-xr-x.1wwwwww1021月1911:06lib
-rw-r--r--.1wwwwww228551月1911:25test.phar
7)执行文件
Shell
[root@bogon phar-sample]# php test.phar
Hello World!
//到这里test.phar可以单独发布执行力。也可以在其他项目(比如WEB)里面引用,例如
include 'test.phar';
//引用里面的文件
//include 'phar://test.phar/app/HelloWorld.php';
1
2
3
4
5
6
7
8
[root@bogonphar-sample]# php test.phar
HelloWorld!
//到这里test.phar可以单独发布执行力。也可以在其他项目(比如WEB)里面引用,例如
include'test.phar';
//引用里面的文件
//include'phar://test.phar/app/HelloWorld.php';
8 )直接可运行的Phar包
如果想做成直接可运行的Phar包,可以像单个PHP可执行文件那样在文件开头加上:#!/usr/bin/env php
PHP
$phar->setStub("#!/usr/bin/env php
Phar::mapPhar('{$file}');
require 'phar://{$file}/index.php';
__HALT_COMPILER();
?>");
//运行命令:
./test.phar
1
2
3
4
5
6
7
8
9
$phar->setStub("#!/usr/bin/env php
Phar::mapPhar('{$file}');
require'phar://{$file}/index.php';
__HALT_COMPILER();
?>");
//运行命令:
./test.phar
参考链接:
安装OpenResty(nginx+lua)开发环境并正常运行 下一篇: Beanstalk服务安装及PHP队列开发