ホームページ >バックエンド開発 >PHPチュートリアル >PHPによるpharの詳細な分析
この記事では、PHP に関する関連知識をお届けします。主に phar に関する関連コンテンツを紹介します。phar の正式名は PHP Archive です。phar 拡張機能は、PHP アプリケーション全体を統合する方法を提供します。移動やインストールを容易にするために、pha ファイルに入れる方法を見てみましょう。
推奨学習: 「PHP ビデオ チュートリアル 」
Jar (Java アーカイブ) ファイルは、すべての実行可能ファイルとアクセス可能なファイルを含むアプリケーションを JAR ファイルにパッケージ化するため、展開プロセスが非常に簡単になります。
JAR に似ています。 phar の完全な名前は PHP Archive です。phar 拡張子は、PHP アプリケーション全体を .phar ファイルに入れて、移動とインストールを容易にする方法を提供します。 phar ファイルの最大の特徴は、複数のファイルを 1 つのファイルに結合する便利な方法であることです。 .phar ファイルは、完全な PHP プログラムを 1 つのファイルに配布し、そのファイルから実行する方法を提供します。
Phar は、JAR とは異なり、PHP 自体で処理できるため、作成または使用するために追加のツールを使用する必要はなく、PHP スクリプトを使用して作成または抽出できます。
。
PHAR ファイルのデフォルトの状態は次のとおりです。読み取り専用 。Phar ファイルの使用には構成は必要ありません。導入は非常に簡単です。独自の Phar ファイルを作成する必要があるため、Phar ファイルへの書き込みを許可する必要があります。これを変更する必要があります。php.ini
私の php.ini ファイルでは、phar.読み取り専用 = オン。
[Phar] ; http://php.net/phar.readonly ;phar.readonly = On
まず、php.ini の phar.readonly オプションを変更し、先行するセミコロンを削除し、値を off に変更します。セキュリティ上の理由により、このオプションのデフォルトは on です。php で無効になっている場合は、 ini (値は 0 または off) にすると、ユーザー スクリプトでオンまたはオフにできます。php.ini でオンになっている場合、ユーザー スクリプトはオフにできないため、ここでは表示するためにオフに設定されています。例。
これで、PHP アプリケーションを Phar ファイルにパッケージ化できます。
ここでは、他の人のブログ プロジェクトから直接コピーしましたが、このブログを構成する当初の目的は phar:/ を理解することであったため、実演はしませんでした。 / 脆弱性がある場合は、ctf を使用してください。したがって、ファイル名は元の作成者に従って変更されません。参考記事は最後に追記します。
まず、アプリケーションのディレクトリ構造をルールに従って作成する必要があります。ルート ディレクトリはプロジェクトで、プロジェクト配下のディレクトリは次のとおりです。空のコンテンツを持つ JS ファイルと CSS ファイルの 2 つのファイル フォルダーがあります。複数のファイル形式を含めることができるのはデモンストレーション phar のみです。
lib_a.php のコンテンツは次のとおりです。
file -yunek.js -yunke.css lib -lib_a.php template -msg.html index.php Lib.php
msg.html のコンテンツは次のとおりです。 :
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/10 * Time: 9:23 */ function show(){ echo "l am show()"; }
index.php の内容は次のとおりです:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>phar</title> </head> <body> <?=$str; ?> </body> </html>
Lib.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";
3 phar ファイルの作成
<?php /** * Created by yunke. * User: yunke * Date: 2017/2/10 * Time: 9:20 */ function yunke() { echo "l am yunke()"; }
次に、ブラウザで yunkeBuild.php ファイルにアクセスします。このとき、サーバーのルートディレクトリ構造は次のようになります:
project
yunkeBuild.php
yunke.phar
これは、phar アーカイブ ファイルを生成する最も簡単なプロセスです。
ここでは、理解を深めるためにその他の追加をいくつか行います:1)
phar ファイルは、yunkeBuild.php にアクセスすることで生成されます。実行。したがって、ターミナルで次のコードを実行して2) 新しい オブジェクトの作成には、通常 3 つのパラメーターが必要です。 2 番目のパラメータは、 オブジェクトがファイルを処理する方法を設定することです。 通常はファイル名を渡すだけです。それが 3 番目のパラメータです。 3) 调用类方法 这里出现的phar://就是访问phar文件的一种方法,所以不需要太在意。 以字符串添加文件内容 调用类方法 调用类方法 调用类方法 4) 存根文件Stub,理解这个很重要。 归档文件中有一个存根文件stub,其实就是一段php执行代码,在制作归档时可以设置,直接执行归档文件时,其实就是执行它,所以它是启动文件;在脚本中包含归档文件时就像包含普通php文件一样包含它并运行,但直接以phar://的方式包含归档中某一个文件时不会执行存根代码, 往往在存根文件里面require包含要运行的其他文件,对存根文件的限制仅为以__HALT_COMPILER(); 结束,默认的存根设计是为在没有phar扩展时能够运行,它提取phar文件内容到一个临时目录再执行,不过从php5.3开始该扩展默认内置启用了。 stub是phar文件的文件头,格式为 其他的方式如下: 方法一:调用类方法 也可以 生成的缺省stub文件包含如下的代码: 除此之外,我们还可以创建自己的stub文件来执行自定义的初始化过程,像这样加载自定义文件 方法二:使用默认stub,调用类方法 如果缺省创建stub,PHP会使用默认stub 我们在服务器根目录建立一个index.php文件来演示如何使用上面创建的phar文件,内容如下: 如果index.php文件中只有第一行,那么和不使用归档文件时,添加如下代码完全相同: 如果没有第二行,那么第三行的yunke()将提示未定义,所以可见require一个phar文件时并不是导入了里面所有的文件,而只是导入了入口执行文件而已,但在实际项目中往往在这个入口文件里导入其他需要使用的文件,在本例中入口执行文件为project/index.php。 补充: 可以为归档设置别名,别名保存在归档文件中永久保存,它可以用一个简短的名字引用归档,而不管归档文件在文件系统中存储在那里,设置别名: 设置别名后可以如下使用: 如果在制作phar文件时没有指定别名,也可以在存根文件里面使用Phar::mapPhar('yunke.phar');指定。 我们有时候会好奇phar里面包含的文件源码,这个时候就需要将phar文件还原,如果只是看一看的话可以使用一些ide工具,比如phpstorm 10就能直接打开它,如果需要修改那么就需要提取操作了,为了演示,我们下载一个composer.phar放在服务器目录,在根目录建立一个get.php文件,内容如下 用浏览器访问这个文件,即可提取出来,以上列子展示了两种提取方式: 2 行目は、composer ディレクトリを作成し、抽出したコンテンツをそこに置きます; 3 行目は、composer.zip ファイルを生成します。このファイルは、解凍することで抽出および復元できます。 phar:// 疑似プロトコルによって引き起こされるサーバー検証バイパスについて: 推奨される学習: 「PHP ビデオ チュートリアル 」 以上がPHPによるpharの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。<?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');
を生成すると、yunke.phar ファイルが生成されます。 aabouzekry@platinum:~/myapp$ php yunkeBuild.php
説明: 最初のパラメータは Phar ファイルへのパスです。それを通じて Phar ファイルを作成できるだけでなく、既存の Phar ファイルを操作することもできます。
Phar
オブジェクトは PHP RecursiveDirectoryIterator
オブジェクトを継承し、このパラメータは親クラスに直接渡されます。ここで指定される値は RecursiveDirectoryIterator
のデフォルト値であり、現在の要件を満たすことができます。 3 番目のパラメータは Phar ファイルのエイリアスです。この Phar ファイルを内部で参照する場合、このエイリアスを使用する必要があります。
Phar::addFile($filepath,$localpath=?)
添加文件,参数是文件绝对路径和(可选)存储到phar的相对路径<?php
$phar = new Phar('yunke.phar');
$phar->addFile('test.php');
include('phar://yunke.phar/test.php') // in test.php
?>
Phar::addFromString($localpath,$contents)
以字符串形式添加文件<?php
$phar = new Phar('yunke.phar');
$phar->addFromString('test.php','<?php echo \'in test.php\'?>');
include('phar://yunke.phar/test.php'); // in test.php
?>
Phar::addEmptyDir($dirname)
添加空目录,使用方法Phar::getContent()
获取文件结构<?php
$phar = new Phar('yunke.phar');
$phar->addEmptyDir('test'); // yunke.phar/test/
?>
Phar::buildFromDirectory($dir,$pattern = "")
添加整个目录<?php
$phar = new Phar('yunke.phar');
$phar->buildFromDirectory('test'); // test.php in test/
include('phar://yunke.phar/test/test.php'); // in test/test.php
?>
...<?php ...;__HALT_COMPILER();?>
,…可以是任意字符,包括留空,且php闭合符与最后一个分号之间不能有多于一个的空格符。另外php闭合符也可省略。最短省略闭合符的stub是__HALT_COMPILER();?></p>
<p>运行Phar文件时,stub文件被当做一个meta文件来初始化Phar, 并告诉Phar文件在被调用时该做什么。</p>
<p>在我们的例子中,使用的是 <code>createDefaultStub() 方法。Phar::setStub($string)
为实例创建自定义stub<?php
$phar = new Phar('yunke.phar');
$phar->setStub('<?php echo \'in stub!\';__HALT_COMPILER();?>');
include('phar://yunke.phar'); // in stub!
?>
$phar->setStub($phar->createDefaultStub("index.php"));
<?php
Phar::mapPhar();
include "phar://yunke.phar/index.php";
__HALT_COMPILER();
createDefaultStub()
方法缺省创建的stub文件的内容很简单。 Phar::mapPhar()
用来分析Phar文件的元数据,并初始化它。stub文件的结尾处需要调用 __HALT_COMPILER()
方法,这个方法后不能留空格。__HALT_COMPILER()
会立即终止PHP的运行,防止include的文件在此方法后仍然执行。这是Phar必须的,没有它Phar将不能正常运行。<?php
$phar->setStub(file_get_contents("stub.php"));
Phar::setDefaultStub()
为实例设置默认stub,使用方法Phar::getStub()
获取实例的stub<?php
$phar = new Phar('yunke.phar');
$phar->setDefaultStub();
print_r($phar->getStub()); // 2, 'c' => 'text/plain', 'cc' => 'text/plain', ...
?>
<?php
$phar = new Phar('yunke.phar');
$phar['demo.txt'] = 'demo';
print_r($phar->getStub()); // 2, 'c' => 'text/plain', 'cc' => 'text/plain', ...
?>
4 phar文件的运行
<?php
/**
* Created by yunke.
* User: yunke
* Date: 2017/2/8
* Time: 9:33
*/
require "yunke.phar";
require "phar://yunke.phar/Lib.php";
yunke();
require "project/index.php";
$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"; //当然仍然可以使用这样的方式去引用
5 phar文件的提取还原
<?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); //另外再提取一份,和上行二选一即可