>  기사  >  백엔드 개발  >  PHP에서 Phar 코드 패키징 도구를 사용하는 방법

PHP에서 Phar 코드 패키징 도구를 사용하는 방법

醉折花枝作酒筹
醉折花枝作酒筹앞으로
2021-06-18 17:09:102881검색

이 글에서는 PHP에서 Phar 코드 패키징 도구를 사용하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

PHP에서 Phar 코드 패키징 도구를 사용하는 방법

Phar 코드 패키징 도구 사용법에 대해 간단히 이해하세요.

Phar는 PHP5 이후에 제공되는 코드 패키징과 유사한 도구입니다. 본질적으로 Java Jar 파일 형태의 코드 패키지입니다. 그러나 PHP 자체가 컴파일되지 않기 때문에 이 Phar는 실제로 컴파일하지 않고 코드를 그대로 패키징합니다. 하지만 패키지된 Phar 패키지를 압축할 수 있습니다.

게다가 실제로 Phar 패키지를 사용해 본 사람은 거의 없습니다. 특히 Composer가 사실상의 코드 기반 표준이 된 오늘날에는 Phar를 찾기가 더욱 어렵습니다. 그러나 Composer 설치 패키지 자체도 .phar 패키징 파일입니다.

주된 이유 중 하나는 Phar 형태의 코드 패키지 설치가 Composer만큼 간단하고 편리하지 않다는 것입니다. 반면에 초기 프로그래머, 특히 LAMP/LAMP 프로그래머는 오픈 소스 설치를 선호합니다. 툴킷을 직접 사용하는 대신 코드를 작성하세요.

결국 소스 코드를 손에 쥐고 있으면 우리가 더 편해집니다. 실제로 컴포저가 소스코드를 직접 다운로드하더라도 실제로 살펴보는 사람은 아무도 없다. Phar에 비해 Composer의 가장 큰 장점은 코드 자동 로딩과 표준 PSR 명령 공간 및 디렉터리 사양입니다. 이 두 가지는 Phar에서 사용할 수 없으므로 Phar 패키지를 사용하려면 이 두 가지를 요구해야 합니다.

낡았지만 우리는 여전히 간략하게 배우고 이해하고 있습니다. 어쩌면 우리는 특히 일부 내부 공용 라이브러리 기능을 캡슐화할 때 Phar의 코드 패키징 방식이 여전히 매우 유용할 때 이를 사용할 수 있을 것입니다.

코드 패키징

먼저 표준 형식의 디렉터리 트리를 만듭니다.

PHP에서 Phar 코드 패키징 도구를 사용하는 방법

이 디렉터리 트리에서 src 디렉터리는 소스 코드를 저장하고, 빌드 디렉터리는 생성된 .phar 코드 패키지를 저장하는 데 사용됩니다.

// index.php
<?php

require_once "phar://myphar.phar/common.php";

index.php 파일에서는 단순히 common.php를 참조합니다. phar 의사 프로토콜은 common.php 파일을 로드하는 데 사용됩니다. 우리는 이전에 기사에서 의사 프로토콜의 내용을 설명했습니다.

<?php
// common.php
class Manager{

    public static function run($config){
        echo "AAA", PHP_EOL;
        var_dump($config);
    }

    public static function ChineseMobile($mobile){
        if(preg_match("/^1[34578]\d{9}$/", $mobile)){
            return true;
        }
        return false;
    }
}

common.php 파일은 테스트를 위한 클래스와 두 가지 간단한 방법만 제공합니다. run() 메소드는 단순히 인쇄된 내용과 전달된 매개변수를 출력합니다. ChineseMobile() 메소드는 국내 휴대폰 번호를 확인할 수 있도록 제공하는 함수입니다.

[database]
host=localhost
db=dbname
user=myuser
pass=dbpass

config.ini는 구성 파일입니다. 실제로 Phar 코드에서 구성 파일을 직접 읽을 수도 있고, 코드와 함께 지정된 디렉터리에 구성 파일을 빌드할 수도 있습니다.

소스 코드 파일이 준비되었으며 다음 단계는 패키지된 컴파일 파일을 준비하는 것입니다.

// create-phar.php
$srcRoot = "./myphar/src";
$buildRoot = "./myphar/build";
 
$phar = new Phar($buildRoot . "/myphar.phar", 
  FilesystemIterator::CURRENT_AS_FILEINFO |       FilesystemIterator::KEY_AS_FILENAME, "myphar.phar");
$phar["index.php"] = file_get_contents($srcRoot . "/index.php");
$phar["common.php"] = file_get_contents($srcRoot . "/common.php");
$phar->setStub($phar->createDefaultStub("index.php"));

copy($srcRoot . "/config.ini", $buildRoot . "/config.ini");

코드는 복잡하지 않습니다. 주로 Phar 클래스입니다. 이 클래스는 생성된 파일의 디렉터리와 파일 이름을 지정한 다음 createDefaultStub() 메서드를 사용하여 패키지의 항목 파일 index.php를 호출합니다. 메서드는 .phar 파일의 지정된 A 스텁을 만드는 데 사용됩니다. 실제로 Java의 main() 메소드 항목과 마찬가지로 항목 파일을 지정하는 것입니다.

그런 다음 config.ini 파일을 릴리스 디렉터리 build에 복사했습니다.

그런 다음 명령줄을 사용하여 create-phar.php 파일을 실행하여 이 코드 패키지를 생성하세요.

# php ./create-phar.php

PHP에서 Phar 코드 패키징 도구를 사용하는 방법

텍스트 편집기를 사용하여 myphar.phar 파일을 엽니다. 아래쪽으로 스크롤하면 index.php 및 common의 내용이 여전히 있음을 알 수 있습니다. php는 모두 여기 파일에 컴파일되어 있습니다. 위의 자동 생성 코드는 Phar 확장 프로그램에서 준비된 일부 부트스트래핑 또는 사전 준비된 명령문입니다. 사용자가 작성한 모든 소스 코드는 이 파일의 맨 아래에 있습니다. 즉, .phar 파일인 Composer 설치 패키지를 다운로드하여 그 안에 무엇이 쓰여 있는지 확인할 수 있습니다.

다음 단계는 사용하는 것입니다. 매우 간단합니다.

$config = parse_ini_file("./myphar/build/config.ini");
require &#39;./myphar/build/myphar.phar&#39;;

Manager::run($config);
// AAA
// array(4) {
//   ["host"]=>
//   string(9) "localhost"
//   ["db"]=>
//   string(6) "dbname"
//   ["user"]=>
//   string(6) "myuser"
//   ["pass"]=>
//   string(6) "dbpass"
// }

var_dump(Manager::ChineseMobile(&#39;13811111111&#39;));
var_dump(Manager::ChineseMobile(&#39;138111111112&#39;));
// bool(true)
// bool(false)

압축 기능

앞서 언급했듯이 Phar는 코드 라이브러리로서 오랫동안 Composer에 패했지만 일부 설치 패키지로 사용되는 것 외에도 Phar 자체도 압축 도구입니다. 일부 파일, 텍스트, 디렉토리 등을 보관하는 데 사용할 수 있습니다. 다음으로 Phar가 텍스트 보관에 어떻게 사용되는지 간략하게 살펴보겠습니다.

unlink(&#39;./my.phar&#39;);
unlink(&#39;./my.phar.bz2&#39;);
unlink(&#39;./my.phar.gz&#39;);
$p = new Phar(&#39;./my.phar&#39;, 0 ,&#39;my.phar&#39;);
$p[&#39;myfile1.txt&#39;] = &#39;hi1&#39;;
$p[&#39;myfile2.txt&#39;] = &#39;hi2&#39;;
$p1 = $p->compress(Phar::GZ);
$p2 = $p->compress(Phar::BZ2);
unset($p);

$decompressPhar  = new Phar(&#39;./my.phar&#39;, 0 ,&#39;my.phar&#39;);
foreach($decompressPhar as $file){
    // $file 是返回的 PharFileInfo 对象
    var_dump($file->getFileName());
    var_dump($file->isCompressed());
    var_dump($file->isCompressed(Phar::BZ2));
    var_dump($file->isCompressed(Phar::GZ));
    var_dump($file->getContent());
}
echo &#39;==================&#39;, PHP_EOL;
// string(11) "myfile1.txt"
// bool(false)
// bool(false)
// bool(false)
// string(3) "hi1"
// string(11) "myfile2.txt"
// bool(false)
// bool(false)
// bool(false)
// string(3) "hi2"

首先,依然是实例化一个 Phar 类,然后我们给它像数组一样增加属性,这样,属性内容就被打包进了 .phar 文件中。通过直接查看 my.phar 文件,我们可以看出,myfile1.txt 这两个属性直接被写成了文件进行保存了,也就是说,它帮我们将文本转化成文件并打包在了 my.phar 这个压缩包文件中了。

compress() 方法则是将当前的这个 Phar 对象压缩存储为某个格式的文件。这里我们直接压缩了 Bzip2 和 GZ 文件。调用这个方法后直接就会生成对应的压缩文件。

Phar 对象在遍历时产生的对象是 PharFileInfo 对象,它拥有很多类似于 File 的文件操作函数。大家可能在官方文档中找到相关的说明。

假设我们遍历 my.phar.gz ,内容依然可以正常输出,但循环中的 isCompressed() 判断都依然会是 false ,难道文件没有被压缩吗?其实,我们需要通过另一个函数来让所有文件都进行统一格式的压缩。

$p = new Phar(&#39;./my.phar&#39;, 0 ,&#39;my.phar&#39;);
$p->compressFiles(Phar::GZ);
unset($p);

$decompressPhar  = new Phar(&#39;./my.phar.gz&#39;, 0 ,&#39;my.phar&#39;);
foreach($decompressPhar as $file){
    // $file 是返回的 PharFileInfo 对象
    var_dump($file->getFileName());
    var_dump($file->isCompressed());
    var_dump($file->isCompressed(Phar::BZ2));
    var_dump($file->isCompressed(Phar::GZ));
    var_dump($file->getContent());
}
echo &#39;==================&#39;, PHP_EOL;

// string(11) "myfile1.txt"
// bool(true)
// bool(false)
// bool(true)
// string(3) "hi1"
// string(11) "myfile2.txt"
// bool(true)
// bool(false)
// bool(true)
// string(3) "hi2"

使用 compressFiles() 对整个 .phar 中的所有文件进行了统一的格式压缩之后,再打印时 isCompressed() 就会返回对应格式的 true 了。

数据格式 Phar

最后,如果只是为了打包压缩功能的话,我们没必要使用 Phar 类。Phar 类最主要的还是用来打包能够运行的 PHP 源码,也就是它的 createDefaultStub() 方法非常重要。而如果只是打包普通文件的话,我们并不需要这个方法,这时,我们就可以使用另外一个 PharData 类来进行数据的打包压缩。使用方法和 Phar 类是一模一样的。同时,PharData 类可以直接打包成 tar 之类的文件。

$p = new PharData(&#39;./myData.tar&#39;);
$p[&#39;myfile1.txt&#39;] = &#39;hi1&#39;;
$p[&#39;myfile2.txt&#39;] = &#39;hi2&#39;;

foreach($p as $file){
    var_dump($file->getFileName());
    var_dump($file->isCompressed());
    var_dump($file->isCompressed(Phar::BZ2));
    var_dump($file->isCompressed(Phar::GZ));
    var_dump($file->getContent());
}
echo &#39;==================&#39;, PHP_EOL;
// string(11) "myfile1.txt"
// bool(false)
// bool(false)
// bool(false)
// string(3) "hi1"
// string(11) "myfile2.txt"
// bool(false)
// bool(false)
// bool(false)
// string(3) "hi2"

总结

说实话,Phar 真的是一个冷门项目,但是在某些情况中又非常有用,比如它虽然在代码包领域被 Composer 打败了,但是它又可以成为 Composer 的安装包,也就是说,没有 Phar 你就安装不了 Composer 。而做为压缩工具,虽然有强大的实力但使用的却也非常的少。因此,我们还是以了解为目的,如果感觉某些场景非常合适的话,也完全可以深入的研究拿来放到我们的实际项目中使用。毕竟它是 PHP 的一部分,不需要任何的编译安装及其它支持,非常原生。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202007/source/%E7%AE%80%E5%8D%95%E4%BA%86%E8%A7%A3Phar%E4%BB%A3%E7%A0%81%E6%89%93%E5%8C%85%E5%B7%A5%E5%85%B7%E7%9A%84%E4%BD%BF%E7%94%A8.php

推荐学习:php视频教程

위 내용은 PHP에서 Phar 코드 패키징 도구를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제