精品网站建设费用磐石网络名气,好的网站 具备,网站 目录访问,龙岩市城乡建设局网站进不去有很多php脚本工具都是打包成phar形式#xff0c;使用起来就很方便#xff0c;那么如何自己做一个呢#xff1f;也找了很多文档#xff0c;也遇到很多坑#xff0c;这里就来总结一下 phar安装
现在直接装yum php-cli包就有phar文件#xff0c;很方便 可通过phar help查看… 有很多php脚本工具都是打包成phar形式使用起来就很方便那么如何自己做一个呢也找了很多文档也遇到很多坑这里就来总结一下 phar安装
现在直接装yum php-cli包就有phar文件很方便 可通过phar help查看帮助
重要修改
php配置文件中
;phar.readonly On
一定要改成
phar.readonly Off phar简单打包
先打包跟简单的单文件
先写一个简单的index.php文件
?php
echo HelloWorld\n;
打包
phar pack -f helloworld.phar -c gz -b #!/usr/bin/php index.php
参数说明
选中描述-f指定生成的phar文件名-c指定压缩算法-b在首行添加内容(可直接执行类似于sh)(单文件时未生效) 执行
php helloworld.phar
则会输出helloworld
如果文件名不是index.php呢
[rootlocalhost test]# phar pack -f helloworld.phar -c gz -b #!/usr/bin/php helloworld.php
helloworld.php
[rootlocalhost test]# php helloworld.phar
PHP Warning: include(phar:///tmp/test/helloworld.phar/index.php): Failed to open stream: phar error: index.php is not a file in phar /tmp/test/helloworld.phar in /tmp/test/helloworld.phar on line 9
PHP Warning: include(): Failed opening phar:///tmp/test/helloworld.phar/index.php for inclusion (include_pathphar:///tmp/test/helloworld.phar:.:/opt/remi/php83/root/usr/share/pear:/opt/remi/php83/root/usr/share/php:/usr/share/pear:/usr/share/php) in /tmp/test/helloworld.phar on line 9
[rootlocalhost test]#
打包虽然没报错但运行找不到index.php文件
通过查看help看到可以使用-s设置启动文件(使用-s时后面...文件中可省略该文件但单文件种情况还是要把单文件加上)
满怀期待的你是不是跃跃欲试了
rootlocalhost test]# phar pack -f helloworld.phar -s helloworld.php
PHP Fatal error: Uncaught PharException: illegal stub for phar /tmp/test/helloworld.phar (__HALT_COMPILER(); is missing) in phar:///opt/remi/php83/root/usr/bin/phar.phar/pharcommand.inc:534
Stack trace:
#0 phar:///opt/remi/php83/root/usr/bin/phar.phar/pharcommand.inc(534): Phar-setStub()
#1 phar:///opt/remi/php83/root/usr/bin/phar.phar/pharcommand.inc(592): PharCommand-phar_set_stub_begin()
#2 phar:///opt/remi/php83/root/usr/bin/phar.phar/clicommand.inc(87): PharCommand-cli_cmd_run_pack()
#3 /opt/remi/php83/root/usr/bin/phar.phar(52): CLICommand-__construct()
#4 {main}thrown in phar:///opt/remi/php83/root/usr/bin/phar.phar/pharcommand.inc on line 534
[rootlocalhost test]#
哈哈报错了
注意-s指定的文件行尾必须要加上__HALT_COMPILER();
helloworld.php代码如下
?php
echo Hello Wolrd\n;
__HALT_COMPILER();
[rootlocalhost test]# phar pack -f helloworld.phar -s helloworld.php helloworld.php
helloworld.php
[rootlocalhost test]# php helloworld.phar
Hello Wolrd
[rootlocalhost test]#
打包通过运行成功 phar多文件打包
比较单文件打包坑点比较多最大的问题是路径问题
先写2个文件
├── helloworld.php
├── lib
│ └── app.php
└── start.php
?php
//helloworld.php
include __DIR__ . /lib/app.php;
echo DIR: . __DIR__ . \n;
echo FILE: . __FILE__ . \n;
$app new app();
$app-show();
echo HelloWorld\n;
?php
//lib/app.php
class app {function show() {echo AppName: . __CLASS__ . \n;echo AppFunc: . __FUNCTION__ . \n;echo AppDir: . __DIR__ . \n;echo AppFile: . __FILE__ . \n;}
}
不建议直接改helloworld.php,要改的很多,不是简单的添加__HALT_COMPILER();
不死心的小伙伴可以试试
强烈建议重新写一个启动文件
这里经过不断尝试整理出来比较简单的写法模板化后面完全可以全部套用
?php
//start.php
//工作目录切换到文件所在目录否则不在文件目录执行会报错
chdir(__DIR__);
//Phar::mapPhar();这样也能通过
Phar::mapPhar(helloworld.phar);
//只能用phar路径否则不通过
require_once phar://helloworld.phar/helloworld.php;
//必须要加否则stub-set会报错
__HALT_COMPILER();
[rootlocalhost test]# phar pack -f bin/helloworld.phar -c gz -b #!/usr/bin/php -s start.php helloworld.php lib/app.php
helloworld.php
lib/app.php
[rootlocalhost test]# chmod ax bin/helloworld.phar
[rootlocalhost test]# ./bin/helloworld.phar
DIR:phar:///tmp/test/bin/helloworld.phar
FILE:phar:///tmp/test/bin/helloworld.phar/helloworld.php
AppName:app
AppFunc:show
AppDir:phar:///tmp/test/bin/helloworld.phar/lib
AppFile:phar:///tmp/test/bin/helloworld.phar/lib/app.php
HelloWorld
[rootlocalhost test]#
多文件的-b参数就有效果
特别注意如果有多级目录不能只写目录名否则路径就会不对(-s文件可在文件列表中省略)
-s start.php helloworld.php lib/app.php
支持匹配写法
-s start.php *.php lib/*.php
下面这种绝对不行虽然help中说可以是目录名
[rootlocalhost test]# phar pack -f bin/helloworld.phar -c gz -b #!/usr/bin/php -s start.php helloworld.php lib
helloworld.php
app.php
[rootlocalhost test]# ./bin/helloworld.phar
PHP Parse error: Unclosed { on line 4 in phar:///tmp/test/bin/helloworld.phar/lib/app.php on line 6
[rootlocalhost test]#
文件直接找不到了看打包时的文件名就可以看出文件路径就不对了 Phar其它注意点
从上面的dir输出就可以看到里面文件或目录都是一种虚拟路径
实际过程中涉及到的文件及目录操作都需要特殊注意
坑爹示范
//helloworld.php
include __DIR__ . /lib/app.php;
echo DIR: . __DIR__ . \n;
echo FILE: . __FILE__ . \n;
echo PharTrue: . Phar::running(true) . \n;
echo PharFalse: . Phar::running(false) . \n;
echo CWD: . getcwd() . \n;
$app new app();
$app-show();
echo HelloWorld\n;
$filename__DIR__./aaa.txt;
file_put_contents($filename, HelloWorld);
?php//lib/app.php
class app {function show() {echo AppName: . __CLASS__ . \n;echo AppFunc: . __FUNCTION__ . \n;echo AppDir: . __DIR__ . \n;echo AppFile: . __FILE__ . \n;echo AppPharTrue: . Phar::running(true) . \n;echo AppPharFalse: . Phar::running(false) . \n;echo AppCWD: . getcwd() . \n;$filename __DIR__ . /bbb.txt;file_put_contents($filename, HelloWorld);}}
使用了file_put_contents
不打包应该这样
[rootlocalhost test]# php helloworld.php
DIR:/tmp/test
FILE:/tmp/test/helloworld.php
PharTrue:
PharFalse:
CWD:/tmp/test
AppName:app
AppFunc:show
AppDir:/tmp/test/lib
AppFile:/tmp/test/lib/app.php
AppPharTrue:
AppPharFalse:
AppCWD:/tmp/test
HelloWorld
打包后第一次看着通过(有的会报错)
[rootlocalhost test]# phar pack -f helloworld.phar -c gz -b #!/usr/bin/php -a helloworld.phar -s start.php helloworld.php lib/app.php
helloworld.php
lib/app.php
[rootlocalhost test]# phar list helloworld.phar
Unexpected default arguments to command list, check /usr/bin/phar help
[rootlocalhost test]# phar list -f helloworld.phar
|-phar:///tmp/test/helloworld.phar/helloworld.php
\-phar:///tmp/test/helloworld.phar/lib\-phar:///tmp/test/helloworld.phar/lib/app.php
[rootlocalhost test]# php helloworld.phar
DIR:phar:///tmp/test/helloworld.phar
FILE:phar:///tmp/test/helloworld.phar/helloworld.php
PharTrue:phar:///tmp/test/helloworld.phar
PharFalse:/tmp/test/helloworld.phar
CWD:/tmp/test
AppName:app
AppFunc:show
AppDir:phar:///tmp/test/helloworld.phar/lib
AppFile:phar:///tmp/test/helloworld.phar/lib/app.php
AppPharTrue:phar:///tmp/test/helloworld.phar
AppPharFalse:/tmp/test/helloworld.phar
AppCWD:/tmp/test
HelloWorld第一次运行看着正常
[rootlocalhost test]# phar list -f helloworld.phar
|-phar:///tmp/test/helloworld.phar/aaa.txt
|-phar:///tmp/test/helloworld.phar/helloworld.php
\-phar:///tmp/test/helloworld.phar/lib|-phar:///tmp/test/helloworld.phar/lib/app.php\-phar:///tmp/test/helloworld.phar/lib/bbb.txt
[rootlocalhost test]# php helloworld.phar
PHP Notice: require_once(): zlib: data error in /tmp/test/helloworld.phar on line 8
PHP Warning: require_once(phar://helloworld.phar/helloworld.php): Failed to open stream: phar error: internal corruption of phar /tmp/test/helloworld.phar (actual filesize mismatch on file helloworld.php) in /tmp/test/helloworld.phar on line 8
PHP Fatal error: Uncaught Error: Failed opening required phar://helloworld.phar/helloworld.php (include_path.:/opt/remi/php83/root/usr/share/pear:/opt/remi/php83/root/usr/share/php:/usr/share/pear:/usr/share/php) in /tmp/test/helloworld.phar:8
Stack trace:
#0 {main}thrown in /tmp/test/helloworld.phar on line 8
[rootlocalhost test]#
但在看文件列表多了aaa.txt和bbb.txt
并且再运行直接报错了
注意Phar::running(true)的返回
解决方式
如果未使用则返回空可以根据这个来处理文件名 $filename __DIR__ . /bbb.txt;if (!empty(Phar::running(true))) {$filename str_replace(Phar::running(true), getcwd(), $filename);if(!file_exists(dirname($filename))){mkdir(dirname($filename), 0777, true);}}file_put_contents($filename, HelloWorld);
这样不管打不打包都能正常运行
执行php情况
[rootlocalhost test]# tree
.
├── aaa.txt
├── helloworld.php
├── lib
│ ├── app.php
│ └── bbb.txt
└── start.php
执行phar情况
[rootlocalhost bin]# tree
.
├── aaa.txt
├── helloworld.phar
└── lib└── bbb.txt有更好的方式可以提出来
还有其它参数-i -x 我暂未试出效果有兴趣的可以自己尝试一下