2

file_put_contentsを使用して、相対的に配置されたフォルダーにファイルを作成して入力します。

インクルード パスとファイルの作成に関連するいくつかの奇妙な癖に気づきました。

短いバージョン: イテレーション 2 とイテレーション 3 を見てください。前者が失敗するのに後者が機能するのはなぜですか?

反復 1

file_put_contents('../../public/remixes/screenshots/test.txt', $data);

これはうまくいきます。

反復 2

しかし、このモジュールの「ルート」に public ディレクトリがあり、事前に設定されたインクルード パスを使用して直接参照したいと考えています。例えば:

echo(get_include_path()); // this outputs "../../"
file_put_contents('public/remixes/screenshots/test.txt', $data, FILE_USE_INCLUDE_PATH);

エラー: 「ストリームを開けませんでした: そのようなファイルまたはディレクトリはありません」

反復 3

わかりました。PHP のインクルード パスは不安定なので、変なことをして何が起こるか見てみましょう。最初にfopenを使用して実際にファイルを作成してみます。

fopen('../../public/remixes/screenshots/test.txt', 'w');
file_put_contents('public/remixes/screenshots/test.txt', $data, FILE_USE_INCLUDE_PATH);

それは再び機能します... ワット?

反復 4

面白い; 最初に fopen を実行しても問題ありませんが、インクルード パスも使用する必要があります。

fopen('public/remixes/screenshots/test.txt', 'w', 1);
file_put_contents('public/remixes/screenshots/test.txt', $data, FILE_USE_INCLUDE_PATH);

これにより、2 つの「ストリームを開くことができませんでした」というエラーが発生します。だんだん悪くなってる。

反復 5

インクルードパスの「魔法」を省き、それを使用して直接パスを構築します

file_put_contents(get_include_path().'public/remixes/screenshots/test.txt', $data);

これは機能し、私が得ることができる最高のものです。

結論

イテレーション 3 が成功するのに、イテレーション 2 が失敗する理由が不思議に思います。

反復 4 は、fopen に問題があることを意味します (file_put_contents は明らかに fopen / fwrite / fclose の単なるラッパーであるため)。

考え?

4

1 に答える 1

0

PHP ソースの検査に少し時間を費やしました。

fopen は/main/streams/streams.cの 2007 行に解決されます

その時点までのスタックは割愛します。

コードの次の部分 (2026 行目) は、FILE_USE_INCLUDE_PATH パラメーターを処理します。

if (options & USE_PATH) {
    resolved_path = zend_resolve_path(path, strlen(path) TSRMLS_CC);
    if (resolved_path) {
        path = resolved_path;
        /* we've found this file, don't re-check include_path or run realpath */
        options |= STREAM_ASSUME_REALPATH;
        options &= ~USE_PATH;
    }
}

実際、通行人がコメントで述べたように、このロジックはパスを解決しようとします。パスが (既存のファイルに) 適切に解決される場合、元のパス文字列は「インクルード化された」パスに置き換えられます。

インクルード化されたパスが既存のファイルを指していない場合、元のパスは置き換えられず、include_path は完全に無視されます。

ドキュメントでは、これが予期される動作であることは明らかではありませんが、この回答へのコメントで指摘されているように、それほどクレイジーではありません。

謎が解けました。

于 2013-03-14T05:57:48.320 に答える