2013-08-20 9 views
6

私のPharスクリプトは、うまく動作するfwriteを使って新しいファイルを作成し、pharファイルと同じディレクトリに新しいファイルを作成します。PHP Phar - file_exists()issue

しかし、私が(file_exists( 'file.php'))を使うと、それを拾いません。

しかし、それを取り込み、それを拾う必要はありません。

誰でもこの問題について知っていますか? しばらくの間、テストとリサーチを行っていると、解決策を見つけることができないようです。

+0

どのバージョンのPHPですか? URLラッパーはverions => PHP 5.0.0 –

+0

のみです。['file_exists()'](http://php.net/file_exists)のドキュメントから次のようにしてみましたか? "注:この関数の結果詳細については、clearstatcache()を参照してください。 –

+0

確かに、私はclearstatcache()を試しました - しかし、キャッシュは '存在する'としてそれを保存し、私の問題はそれが見つからないということです - だからこそ犯人ではありません。 – Lan

答えて

4

PHPでのファイルパスとPharアーカイブでの作業ファイルのパスとPharアーカイブ

での作業は注意が必要です。 Pharファイル内のPHPコードは、相対パスをPharアーカイブの相対パスとして扱います。ではなく、現在の作業ディレクトリに対する相対パスはです。ここでは簡単な例です:

では、次のファイルがあるとしましょう:

phar/index.php 
test.php 
my.phar 

index.phpファイルがpharのディレクトリの内側に位置しています。これは、pharアーカイブのためのブートストラップファイルです:

function does_it_exist($file){ 
    return file_exists($file) ? "true" : "false"; 
} 

のPharファイルはPHPスクリプトから含まれている場合、ブートストラップファイルが実行されます。私たちのブートストラップファイルは単に "does_it_exist"関数を宣言します。

のはtest.phpをの内側に別のコードを実行してみてください、結果は各実行のためのものか見てみましょう:ファイル名を指定して実行4.で

//Run 1: 
require_once 'phar/index.php'; //PHP file 
$file = __DIR__ . "/index.php"; //absolute path 
echo does_it_exist($file);  //prints "false" 

//Run 2: 
require_once 'phar/index.php'; //PHP file 
$file = "index.php";   //relative path 
echo does_it_exist($file);  //prints "false" 

//Run 3: 
require_once 'my.phar';   //phar file 
$file = __DIR__ . "/index.php"; //absolute path 
echo does_it_exist($file);  //prints "false" 

//Run 4: 
require_once 'my.phar';   //phar file 
$file = "index.php";   //relative path 
echo does_it_exist($file);  //prints "true" 

ルックこのコードは、phar形式のファイルが含まれており、機能に相対パスを渡します。現在の作業ディレクトリと比較して、index.phpは存在しません。しかし、pharアーカイブの内容と比べて、それは存在します。それが「真実」をプリントしている理由です!

+0

私は知っている、私は知っている。それは問題ではありません。私のpharパッケージはfwriteを使ってpharスクリプトの外側に新しいファイルを作成します。完全に動作すると、新しいファイルが作成されます。この新機能は後でincludeやrequireで読むことができますが、file_existsによって "見られる"ことはできません - これは私の問題です - pharのバグかもしれません。 – Lan

+0

@Lanはあなたにクエリ – Vineet1982

+0

を返信しましたが、 .php ')またはrequire(' login。(file_exists( 'login.php'))がtrueを返すかどうかを確かめます - 確かにinclude/requireの読み込みがファイルのパス/場所が正しいことを示していることと、問題ではないですか? – Lan

1

ないfile_exists()が失敗することがありますが、PHPでこの

function fileExists($path){ 
    //try to open the file, if it can be read the file exist 
    return (@fopen($path,"r") == true); 
} 
+1

ああ良い考えです。ありがとう。私はそれをより合法に保つために後でそれをfcloseする必要がありますか? – Lan

+1

はい! fopen関数が成功すると、後でそれを閉じることができます。ファイルを閉じ、ファイルを閉じてtrueを返し、そうでない場合はfalseを返します。 – Konsole

2

file_existsのようなものは、特定の場合には、いくつかの問題を持って試すことができます原因を確認してください。

私はPHPで
、一般的にその情報を取得する方法を兼ね備えされ、あなたが代わりにstat()を使用しないことをお勧めします。また、clearstatcache()を呼び出してキャッシュをクリアすることを忘れないでください。

function FileExists($filename) 
{ 
    clearstatcache(false, $filename); 

    return false !== @stat($filename); 
} 

注:私は、私はできる限り抑制オペレーター@は限り回避しようが、私はそれを使用するためにneccessaryとして、この特定のケースを参照してください:)

7

PHARのスタブでは、あなたが__DIR__魔法を使用することができますPHARファイルのフォルダを取得する定数。念頭に置いて

、あなたは単にPHAR外のファイルの存在を確認するには

is_file(__DIR__ . DIRECTORY_SEPARATOR . $path); 

を使用することができます。

これは、スタブからのみ行うことができ、Phar :: setDefaultStub()によって生成されたスタブとは対照的に、カスタムスタブである場合のみ可能です。行の下にあるファイルをチェックする必要がある場合は、グローバル変数、カスタムの非魔法の定数、静的なプロパティなど、他のファイルが参照する定数の値を何らかの形で利用可能にする必要があります。

編集:実際にはdirname(Phar::running(false))を使用して、PHARの任意の場所からPHARのフォルダを取得することもできます。この関数は、PHAR内にない場合は空の文字列を返します。そのため、アプリケーションがPHARとして実行されても直接実行されても、正常に動作するはずです。

$pharFile = Phar::running(false); 
is_file(('' === $pharFile ? '' : dirname($pharFile) . DIRECTORY_SEPARATOR) . $path) 
2

この現象は、Phar::interceptFileFuncs()を呼び出して再現できます。 fopen書き込みモードでの呼び出しはインターセプトされていないようですが、stat関連の関数はそうです。

絶対ファイル名であってもファイル関数をインターセプトPharアーカイブ内のファイルシステムに関連するものとして扱われるので:

[...]の絶対パスがファイルシステムから外部ファイルをロードしようとします。

...問題に対処する一つの方法は、realpath()を使用することです:

if (file_exists(realpath($filename)) { /* file exists on filesystem */ } 
4

今日は同じ問題を満たしています。数時間掘り下げた後...私は答えを見つけた。

次のスクリプトを先に試すことはできますか?

if(file_exists(realpath('file.php'))); 

ファイルが存在する場合、問題は、パス情報なしでファイル名のみを使用する場合、PHPの御馳走ファイルはをpharスタブに関連している

です。例えば:だから

phar:///a/b/c/file.php

、あなたがたとえば、ファイルを操作するための絶対パスを使用する必要があります。

/home/www/d/e/f/file.php

このヘルプを願っています。

マーク