首頁 > 後端開發 > PHP問題 > php如何使用Phar程式碼打包工具

php如何使用Phar程式碼打包工具

醉折花枝作酒筹
發布: 2023-03-10 18:12:01
轉載
2937 人瀏覽過

這篇文章跟大家介紹一下php使用Phar程式碼打包工具的方法。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

php如何使用Phar程式碼打包工具

簡單了解Phar程式碼打包工具的使用

Phar 是在PHP5 之後提供的一種類似於將程式碼打包的工具。基本上就是想依照 Java 的 Jar 檔案那種形式的程式碼包,不過本身由於 PHP 是不編譯的,所以這個 Phar 其實就是將程式碼原樣的進行打包,不會進行編譯。但是我們可以對打包的 Phar 包進行壓縮操作。

另外,實際上使用過 Phar 套件的人非常少,特別是在 Composer 已經成為事實代碼庫標準的今天,Phar 就更難覓食了。不過,Composer 的安裝包本身也是一個 .phar 的打包檔。

最主要的原因,一個是Phar 這種形式的程式碼包安裝並不像Composer 一樣的簡單方便,另一方面,早期的程式設計師,特別是LAMP/LAMP 的程式設計師,都喜歡去將開源的程式碼複製過來,而不喜歡直接使用一個工具包。

畢竟,原始碼在手上讓我們更踏實一些。其實,就算是 Composer 這樣直接下載的就是原始碼,我們也從來沒什麼人真正的去翻過。而 Composer 相比 Phar 的最大優勢,一個是程式碼的自動加載,另一個是標準的 PSR 命令空間和目錄規範。這兩個在 Phar 中是沒有的,所以我們要使用 Phar 套件都必須要 require 一下。

雖然說已經過時了,但我們還是簡單的來學習了解一下。說不定在什麼時候我們就能用上,特別是封裝一些內部的公用函式庫函數時,Phar 打包程式碼的這種方式還是非常有用的。

程式碼打包

我們先按標準格式建立一個目錄樹。

php如何使用Phar程式碼打包工具

在這個目錄樹中,src 目錄存放原始碼,build 目錄用來存放產生後的 .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 的程式碼中直接的進行設定檔的讀取,也可以讓設定檔隨程式碼一起 build 到指定的目錄。

原始碼檔準備好了,接下來就是要準備要打包的編譯檔了。

// 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 檔案的存根。其實就是指定一個入口文件,就像 Java 中的 main() 方法入口一樣。

然後我們拷貝了 config.ini 檔案到發布目錄 build 中。

接著使用命令列運行這個 create-phar.php 文件,就能夠產生這套程式碼包了。

# php ./create-phar.php
登入後複製

php如何使用Phar程式碼打包工具

使用文字編輯器打開myphar.phar 文件,我們會發現裡面竟然還是我們熟悉的PHP 程式碼,拉到最底下,更會發現index.php 和common.php 的內容都被編譯在這個檔案中了。上面的那些自動產生的程式碼就是一些引導或前置準備語句,是 Phar 擴充為我們準備好的內容,所有使用者自己寫的原始碼都會在這個檔案的底部。也就是說,大家可以下載 Composer 的安裝包,也就是那個 .phar 檔案看看裡面都寫了什麼東西。

接下來就是使用了,這個就非常簡單了。

$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中文網其他相關文章!

相關標籤:
php
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板