PHP函数参考05-zip与phar压缩包
目录
Zip扩展
此扩展可以让你透明地读写ZIP压缩文档以及它们里面的文件。
建议使用ZipArchive类库。
一般zip压缩包操作步骤:创建ZipArchive对象,open一个zip文件压缩包,和打开文件函数fopen一样有打开模式mode设置,然后通过getFromIndex、getFromName等方法读取指定压缩包包中的文件内容,addFile、addFromString等方法写Zip包里的文件,也可以通过extractTo方法来解压整个zip包,还可以通过set相关方法修改压缩包的信息。
$zip = new ZipArchive();
$filename = "test.zip";
if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
exit("cannot open <$filename>\n");
}
$zip->setArchiveComment('压缩包说明');
$zip->setPassword("chinese");
$zip->addFromString("testfilephp" . time().".txt", "#1 This is a test string added as testfilephp.txt.\n");
$zip->addFromString("testfilephp2" . time().".txt", "#2 This is a test string added as testfilephp2.txt.\n");
$zip->addFile(__DIR__ . "/test.php","testfromfile.php");
echo "numfiles: " . $zip->numFiles . "\n";
echo "status:" . $zip->status . "\n";
echo "statusSys: " . $zip->statusSys . "\n";
echo "filename: " . $zip->filename . "\n";
echo "comment: " . $zip->comment . "\n";
$zip->close();
打开zip压缩包的模式有:
- ZIPARCHIVE::CREATE(integer) 如果不存在则创建一个zip压缩包。 注意,如果存在相同名字的zip压缩包,并不是直接报错,而是会往zip压缩包里继续写不同的文件。
- ZIPARCHIVE::OVERWRITE(integer) 总是以一个新的压缩包开始,此模式下如果已经存在则会被覆盖。
- ZIPARCHIVE::EXCL(integer) 如果压缩包已经存在,则出错。
- ZipArchive::RDONLY(integer) 只读模式打开压缩包。 需要php7.4以上。
- ZIPARCHIVE::CHECKCONS(integer) 对压缩包执行额外的一致性检查,如果失败则显示错误。
phar包
-
phar包是什么
phar是什么?Phar归档的最佳特点是,它是一种将多个文件分组为单个文件的方便方法。因此,phar归档提供了一种方法,可以将完整的PHP应用程序分发到单个文件中,并从该文件运行它,而不需要将其提取到磁盘。此外,phar归档可以像其他文件一样,在命令行和web服务器上轻松地由PHP执行。Phar有点像PHP应用程序的u盘。
phar扩展提供了一种方法,可以将整个PHP应用程序放入称为“phar”(PHP存档)的单个文件中,以便于分发和安装。除了提供这个服务之外,phar扩展还提供了一个文件-格式抽象方法,用于通过PharData类创建和操作tar和zip文件,很多类PDO提供了一个统一的接口来访问不同的数据库。与不能在不同数据库之间进行转换的PDO不同,Phar还可以使用一行代码在tar、zip和Phar文件格式之间进行转换。
-
为什么phar很少有人用?
PHP5.3 之后支持了类似 Java 的 jar 包,名为 phar。用来将多个 PHP 文件打包为一个文件。这个特性使得 PHP也可以像 Java 一样方便地实现应用程序打包和组件化。一个应用程序可以打成一个 Phar 包,直接放到 PHP-FPM 中运行。
但是除了composer.phar本身以外,实际应用中,各种PHP开源项目以及composer上的各种包的源代码,这个phar并没有很多使用,不像java的jar包一样用途那么广泛。
可能由于LAMP开源的思想深入PHP的程序员思维里,PHPer倾向于开源,一方面对于能看到源代码的包会更放心,另一方面是一种传承下来的学习途径,阅读优秀的源代码,甚至有时还想去调整修改源代码。
-
phar常用的三个类库
phar有三个相关类库:Phar类、PharData类、PharFileInfo类。
Phar类用于可执行的phar包的操作,而PharData类用于制作不可执行的phar包,PharFileInfo类用于读写及设置phar包信息及文件信息,和Phar类部分方法功能一样。
-
phar包制作
phar包,和zip压缩包创建是类似的原理,只是phar包支持了php文件可执行,提供了执行入口设置等。
-
准备一个src目录用于放php源码文件,一个build目录,用于存放编译后的phar包。
-
在src目录中准备index.php与common.php文件:
//common.php function my_print($data){ echo "\n".date("Y-m-d H:i:s")."\n"; echo print_r($data,true); echo "\n"; }
//index.php include_once "phar://app.phar/common.php";//注意,这里我们使用了一个app.phar的别名,这个别名是创建phar的时候为phar设置的别名。 $ini = [ "a"=>"apple", 'b'=>"banana", "c"=>"chinese" ]; my_print($ini);
-
准备创建app.phar包
//phar.php //用于创建app.phar包 $phar = new Phar(__DIR__."/build/app.phar", FilesystemIterator::CURRENT_AS_FILEINFO|FilesystemIterator::KEY_AS_FILENAME,"app.phar"); $phar["index.php"] = file_get_contents(__DIR__ . "/src/index.php"); $phar["common.php"] = file_get_contents(__DIR__ . "/src/common.php"); $phar->setStub($phar->createDefaultStub("index.php"));//设置phar入口文件 //如果还有其他资源文件的话,还可以通过copy函数将需要的资源文件也复制到编译目录build中
执行phar.php脚本后,会在build目录下生成app.phar包文件,如果有报错,注意php.ini中phar.readonly是否设置正确:
jm@ubuntu:/var/www/html/php-shiyanchang/FunctionsReference/build$ ll total 16 drwxrwxr-x 2 jm jm 4096 Feb 11 15:18 ./ drwxrwxr-x 4 jm jm 4096 Feb 11 15:14 ../ -rw-rw-r-- 1 jm jm 7408 Feb 11 15:18 app.phar
-
开启phar读写开关配置
当我们执行phar.php脚本时,会报Fatal error:
PHP Fatal error: Uncaught UnexpectedValueException: creating archive "/var/www/html/php-shiyanchang/FunctionsReference/build/app.phar" disabled by the php.ini setting phar.readonly in /var/www/html/php-shiyanchang/FunctionsReference/phar.php:11
这是因为php.ini中默认phar是只读的,需要将phar.readonly设置为0或Off
[Phar] ; http://php.net/phar.readonly phar.readonly = Off
-
访问或执行phar包
如果在cli模式下,我们可以直接执行phar包:
jm@ubuntu:/var/www/html/php-shiyanchang/FunctionsReference/build$ php app.phar 2020-02-11 15:21:39 Array ( [a] => apple [b] => banana [c] => chinese )
如果我们尝试在web服务里使用phar包,我们可以创建一个runphar.php这样的php文件,include引入phar包,就可以免去在web server上配置如何解析phar包:
//runphar.php include_once 'build/app.phar';
-