2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Phar で実行されているか PHP のスクリプト内から検知(確認)する

Last updated at Posted at 2018-01-31

Phar 内で一緒にアーカイブされているファイルを参照したい

自作した PHP アプリを Box3 などで Phar (PHPアーカイブ)形式で配布する際、アーカイブ前の動作確認含め Phar として呼び出されているか確認したい

例えば、一緒にアーカイブされているファイル( JSON ファイルなど)を file_get_contents() で取得したい場合です。直接実行とアーカイブ経由での実行で、ファイルのパス(表記)が変わるので、条件で分岐させたい場合などです。

TL;DR

Phar::running() メソッドを使って、自身のpharファイルのパスを取得できるか否かで判断する

function isPhar()
{
    return strlen(\Phar::running()) > 0 ? true : false;
}

サンプル

index.php
<?php

echo 'Hello World!' . PHP_EOL;

function isPhar()
{
    return strlen(\Phar::running()) > 0 ? true : false;
}

if (isPhar()) {
    echo 'Running via phar.', PHP_EOL;
    echo 'Path FILE is: '   , __FILE__        , PHP_EOL;
    echo 'Path Phar is: '   , \Phar::running(), PHP_EOL;
} else {
    echo 'Running PHP directly.', PHP_EOL;
    echo 'Path FILE is: '       , __FILE__       , PHP_EOL;
    echo 'Path Phar is: '       , \Phar::running(), PHP_EOL;
}

  • アーカイブの index.php の呼び出し結果サンプル
$ php ./src/index.php
Hello World!
Running PHP directly.
Path FILE is: /path/to/your/src/index.php
Path Phar is: 
  • アーカイブの HelloWorld.phar の呼び出し結果サンプル
$ php ./HelloWorld.phar
Hello World!
Running via phar.
Path FILE is: phar:///path/to/your/HelloWorld.phar/index.php
Path Phar is: phar:///path/to/your/HelloWorld.phar

TS;DR

同じアーカイブ(Phar ファイル)内のファイルにアクセスする際の違い

下記のようなディレクトリ構成を考えます。

ディレクトリ構成
━┳━ src/
 ┃   ┣━ index.php
 ┃   ┗━ sample.json
 ┃
 ┣━ HelloWorld.phar // 'src/' をアーカイブしたもの
 ┣━ box.phar        // アーカイブ・アプリ(Pharアーカイバ) 
 ┗━ box.json        // アーカイブ設定情報 

一般的に、index.phpsample.json を読み込みたい場合はシンプルに file_get_contents() が使えます。

$file_json = file_get_contents('sample.json');

しかし file_get_contents('sample.json'); のままだと、これらの(2 つの)ファイルを HelloWorld.phar にアーカイブした場合に読み込めなくなります。なぜならアーカイブ内ではなく 'HelloWorld.phar' と同じ階層にある sample.json を探しに行ってしまうからです。

そのため、パスを次のように変更しないといけません。

$file_json = file_get_contents('phar://HelloWorld.phar/src/sample.json');

この時 HelloWorld.phar/src/sample.json のパスはアーカイブ内の sample.json を見に行っていることになります。

つまり、Phar の場合とそうでない場合でファイルのパスを分岐する必要があるわけです。

分岐の例

文頭のサンプルを見てわかるように、phar経由で実行している場合 Phar::running メソッドは自身の .phar までのパスを返すので、以下のような PHP/Phar のどちらでも使える汎用的なファイル指定ができます。

Phar内のファイル構成.
HelloWorld.phar/
  ┣━ index.php
  ┗━ sample.json
index.php
<?php

function get_path_root()
{
    if (strlen(\Phar::running()) > 0) {
        $path_file_phar = \Phar::running(false);
        return dirname($path_file_phar) . DIRECTORY_SEPARATOR;
    }
    return __DIR__ . DIRECTORY_SEPARATOR;
}

$name_file_include = 'sample.json';
$path_root         = get_path_root();
$data_json         = file_get_contents($path_root . $name_file_include);

参考文献

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?