一个php应用程序往往是由多个文件构成的,如果能把他们集中为一个文件来分发和运行是很方便的,这样的列子有很多,比如在window操作系统上面的安装程序、一个jquery库等等,为了做到这点php采用了phar文档文件格式,这个概念源自java的jar,但是在设计时主要针对 PHP 的 Web 环境,与 JAR 归档不同的是Phar 归档可由 PHP 本身处理,因此不需要使用额外的工具来创建或使用,使用php脚本就能创建或提取它。phar是一个合成词,由PHP 和 Archive构成,可以看出它是php归档文件的意思。
关于phar的官网文档请见http://php.net/manual/zh/book.phar.php,本文档可以看做和官网文档互为补充
phar归档文件有三种格式:tar归档、zip归档、phar归档,前两种执行需要php安装Phar 扩展支持,用的也比较少,这里主要讲phar归档格式。
phar格式归档文件可以直接执行,它的产生依赖于Phar扩展,由自己编写的php脚本产生。
Phar 扩展对 PHP 来说并不是一个新鲜的概念,在php5.3已经内建于php中,它最初使用 PHP 编写并被命名为 PHP_Archive,然后在 2005 年被添加到 PEAR 库。由于在实际中,解决这一问题的纯 PHP 解决方案非常缓慢,因此 2007 年重新编写为纯 C 语言扩展,同时添加了使用 SPL 的 ArrayAccess 对象遍历 Phar 归档的支持。自那时起,人们做了大量工作来改善 Phar 归档的性能。
Phar 扩展依赖于php流包装器,关于此可参考前面一篇文章PHP流Streams、包装器wrapper概念与用法实例详解
很多php应用都是以phar格式分发并运行的,著名的有依赖管理:composer、单元测试:phpunit,下面我们来看一看如何创建、运行、提取还原。
phar文件的创建:
首先在php.ini中修改phar.readonly这个选项,去掉前面的分号,并改值为off,由于安全原因该选项默认是on,如果在php.ini中是禁用的(值为0或off),那么在用户脚本中可以开启或关闭,如果在php.ini中是开启的,那么用户脚本是无法关闭的,所以这里设置为off来展示示例。
我们来建立一个项目,在服务器根目录中建立项目文件夹为project,目录内的结构如下:
file -yunek.js -yunke.css lib -lib_a.php template -msg.html index.php Lib.php
其中file文件夹有两个内容为空的js和css文件,仅仅演示phar可以包含多种文件格式
lib_a.php内容如下:
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/10 * Time: 9:23 */ function show(){ echo "l am show()"; }
msg.html内容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>phar</title> </head> <body> <?=$str; ?> </body> </html>
index.php内容如下:
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/10 * Time: 9:17 */ require "lib/lib_a.php"; show(); $str = isset($_GET["str"]) ? $_GET["str"] : "hello world"; include "template/msg.html";
Lib.php内容如下:
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/10 * Time: 9:20 */ function yunke() { echo "l am yunke()"; }
项目文件准备好了,开始创建,现在在project文件夹同级目录建立一个yunkeBuild.php,用于产生phar格式文件,内容如下:
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/10 * Time: 9:36 */ //产生一个yunke.phar文件 $phar = new Phar('yunke.phar', 0, 'yunke.phar'); // 添加project里面的所有文件到yunke.phar归档文件 $phar->buildFromDirectory(dirname(__FILE__) . '/project'); //设置执行时的入口文件,第一个用于命令行,第二个用于浏览器访问,这里都设置为index.php $phar->setDefaultStub('index.php', 'index.php');
然后在浏览器中访问这个yunkeBuild.php文件,将产生一个yunke.phar文件,此时服务器根目录结构如下:
project yunkeBuild.php yunke.phar
这就是产生一个phar归档文件最简单的过程了,更多内容请看官网,这里需要注意的是如果项目不具备单一执行入口则不宜使用phar归档文件
phar归档文件的使用:
我们在服务器根目录建立一个index.php文件来演示如何使用上面创建的phar文件,内容如下:
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/8 * Time: 9:33 */ require "yunke.phar"; require "phar://yunke.phar/Lib.php"; yunke();
如果index.php文件中只有第一行,那么和不使用归档文件时,添加如下代码完全相同:
require "project/index.php";
如果没有第二行,那么第三行的yunke()将提示未定义,所以可见require一个phar文件时并不是导入了里面所有的文件,而只是导入了入口执行文件而已,但在实际项目中往往在这个入口文件里导入其他需要使用的文件,在本例中入口执行文件为project/index.php
phar文件的提取还原:
我们有时候会好奇phar里面包含的文件源码,这个时候就需要将phar文件还原,如果只是看一看的话可以使用一些ide工具,比如phpstorm 10就能直接打开它,如果需要修改那么就需要提取操作了,为了演示,我们下载一个composer.phar放在服务器目录,在根目录建立一个get.php文件,内容如下:
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/9 * Time: 19:02 */ $phar = new Phar('composer.phar'); $phar->extractTo('composer'); //提取一份原项目文件 $phar->convertToData(Phar::ZIP); //另外再提取一份,和上行二选一即可
用浏览器访问这个文件,即可提取出来,以上列子展示了两种提取方式:第二行将建立一个composer目录,并将提取出来的内容放入,第三行将产生一个composer.zip文件,解压即可得到提取还原的项目文件。
补充:
1、在部署phar文件到生产服务器时需要调整服务器的配置,避免当访问时浏览器直接下载phar文件
2、可以为归档设置别名,别名保存在归档文件中永久保存,它可以用一个简短的名字引用归档,而不管归档文件在文件系统中存储在那里,设置别名:
$phar = new Phar('lib/yunke.phar', 0); $phar->setAlias ( "yun.phar");
设置别名后可以如下使用:
<?php require "lib/yunke.phar"; require "phar://yun.phar/Lib.php"; //使用别名访问归档文件 require "phar://lib/yunke.phar/Lib.php"; //当然仍然可以使用这样的方式去引用
如果在制作phar文件时没有指定别名,也可以在存根文件里面使用Phar::mapPhar('yunke.phar');
指定
3、归档文件中有一个存根文件,其实就是一段php执行代码,在制作归档时可以设置,直接执行归档文件时,其实就是执行它,所以它是启动文件;在脚本中包含归档文件时就像包含普通php文件一样包含它并运行,但直接以phar://的方式包含归档中某一个文件时不会执行存根代码,
往往在存根文件里面require包含要运行的其他文件,对存根文件的限制仅为以__HALT_COMPILER();
结束,默认的存根设计是为在没有phar扩展时能够运行,它提取phar文件内容到一个临时目录再执行,不过从php5.3开始该扩展默认内置启用了
4、制作的phar文件不能被改动,因此配置文件之类的文件需要另外放置在归档文件外面
5、mapPhar函数:这个函数只应该在stub存根代码中调用,在没有设置归档别名的时候可以用来设置别名,打开一个引用映射到phar流。
大家学会了吗?
相关推荐:
The above is the detailed content of Detailed explanation of the concept and usage of archive format phar file for PHP development. For more information, please follow other related articles on the PHP Chinese website!