PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】


Posted in PHP onNovember 17, 2017

本文实例讲述了PHP开发之归档格式phar文件概念与用法。分享给大家供大家参考,具体如下:

一个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流

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
用PHP连接Oracle数据库
Oct 09 PHP
PHP配置文件中最常用四个ini函数
Mar 19 PHP
PHP Warning: PHP Startup: Unable to load dynamic library \ D:/php5/ext/php_mysqli.dll\
Jun 17 PHP
怎样给PHP源代码加密?PHP二进制加密与解密的解决办法
Apr 22 PHP
PHP生成sitemap.xml地图函数
Nov 13 PHP
php环境下利用session防止页面重复刷新的具体实现
Jan 09 PHP
php数组编码转换示例详解
Mar 11 PHP
PHP实现把文本中的URL转换为链接的auolink()函数分享
Jul 29 PHP
php禁止某ip或ip地址段访问的方法
Feb 25 PHP
PHP中多线程的两个实现方法
Oct 14 PHP
php实现微信企业号支付个人的方法详解
Jul 26 PHP
Laravel 简单实现Ajax滚动加载示例
Oct 22 PHP
PHP流Streams、包装器wrapper概念与用法实例详解
Nov 17 #PHP
PHP实现求两个字符串最长公共子串的方法示例
Nov 17 #PHP
PHP实现求解最长公共子串问题的方法
Nov 17 #PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
Nov 17 #PHP
PHP 实现人民币小写转换成大写的方法及大小写转换函数
Nov 17 #PHP
关于php支持的协议与封装协议总结(推荐)
Nov 17 #PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
Nov 16 #PHP
You might like
PHP下几种删除目录的方法总结
2007/08/19 PHP
php中通过正则表达式下载内容中的远程图片的函数代码
2012/01/10 PHP
php和editplus正则表达式去除空白行
2015/04/17 PHP
PHP7 其他语言层面的修改
2021/03/09 PHP
window.open被浏览器拦截后的自定义提示效果代码
2007/11/19 Javascript
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
2014/08/15 Javascript
JavaScript学习心得之概述
2015/01/20 Javascript
JavaScript常用脚本汇总(一)
2015/03/04 Javascript
javascript实现鼠标移到Image上方时显示文字效果的方法
2015/08/07 Javascript
Javascript中的数组常用方法解析
2016/06/17 Javascript
jQuery查找节点方法完整实例
2016/09/13 Javascript
node.js通过axios实现网络请求的方法
2018/03/05 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
vue webpack开发访问后台接口全局配置的方法
2018/09/18 Javascript
浅谈layui 表单元素的选中问题
2019/10/25 Javascript
微信小程序仿抖音短视频切换效果的实例代码
2020/06/24 Javascript
Vue 解决父组件跳转子路由后当前导航active样式消失问题
2020/07/21 Javascript
JavaScript实现点击切换功能
2021/01/27 Javascript
python中的实例方法、静态方法、类方法、类变量和实例变量浅析
2014/04/26 Python
Python专用方法与迭代机制实例分析
2014/09/15 Python
在Django的视图中使用form对象的方法
2015/07/18 Python
梯度下降法介绍及利用Python实现的方法示例
2017/07/12 Python
python的pdb调试命令的命令整理及实例
2017/07/12 Python
Python序列循环移位的3种方法推荐
2018/04/09 Python
教你利用Python玩转histogram直方图的五种方法
2018/07/30 Python
Python图像处理之颜色的定义与使用分析
2019/01/03 Python
Python实现Excel自动分组合并单元格
2021/02/22 Python
VICHY薇姿英国官网:全球专业敏感肌护肤领先品牌
2017/07/04 全球购物
党校培训思想汇报
2014/01/03 职场文书
信息技术培训感言
2014/03/06 职场文书
幼儿园小班评语
2014/04/18 职场文书
幼儿园小班个人工作总结
2015/02/12 职场文书
时尚女魔头观后感
2015/06/04 职场文书
实验室安全管理制度
2015/08/05 职场文书
法律服务所工作总结
2015/08/10 职场文书
Android Gradle 插件自定义Plugin实现注意事项
2022/06/16 Java/Android