目录

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';