web-dev-qa-db-ja.com

file_get_contentsは空の文字列を返します

奇妙に見えるので、私はこの質問をするのをためらっています。とにかく。誰かが同じ問題にすでに遭遇した場合に備えて...ファイルシステム関数(fopem、file、file_get_contents)は、http://ラッパーに対して非常に奇妙な動作をします

  • 一見動作します。 エラーは発生しません。 fopen()はリソースを返します。
  • 確実に機能しているすべてのURLのデータを返しません(例:http://google.com/)。
    ファイルは空の配列を返し、file_get_contents()は空の文字列を返し、freadはfalseを返します
  • 意図的に間違っているすべてのURL(例:http://goog973jd23le.com/)それはまったく同じように動作し、少し[おそらくドメインルックアップ]タイムアウトを除いて保存します。その後、エラーは発生しませんが(はずですが!)、空の文字列になります。
  • url_fopen_wrapperがオンになっています
  • curl(コマンドラインとphpバージョンの両方)は正常に動作し、他のすべてのユーティリティとアプリケーションは正常に動作し、ローカルファイルは正常に開きます

このエラー は、私の場合、すべてのURLまたはホストで機能しないため、適用できないようです。

php-fpm 5.2.11 Linuxバージョン2.6.35.6-48.fc14.i686([email protected]

21

PHP構成から--with-curlwrapperを削除して再構築することにより、Fedora 14でPHP 5.3.3を実行)で)この問題を修正しました。

23
Eric Caron

バグのように聞こえます。しかし、後世のために、デバッグしたいことがいくつかあります。

  • allow_url_fopen:すでにテスト済み
  • Apacheの下のPHPは、PHP-CLIとは異なる動作をする可能性があり、chroot/selinux/fastcgi/etcにヒントを与えます。セキュリティ制限
  • ローカルファイアウォール:curlが機能するため、可能性は低い
  • ユーザーエージェントのブロック:これは非常に一般的ですが、ウェブサイトはクローラーと不明なクライアントをブロックします
  • iSPからの透過プロキシ、マングルまたはブロック(PHPユーザーエージェントまたは非ユーザーエージェントはマルウェアとして解釈される可能性があります)
  • PHPストリームラッパーの問題

とにかく、まずPHPのストリームハンドラーが機能していることを証明しましょう。

<?php
     if (!file_get_contents("data:,ok")) {
          die("Houston, we have a stream wrapper problem.");
     }

次に、PHPが実際のHTTPリクエストを作成するかどうかを確認します。まず、コンソールでnetcatを開きます。

nc -l 80000

そしてただデバッグする:

<?php
    print file_get_contents("http://localhost:8000/hello");

そして、ここからPHPとの通信を試み、応答を変化させた場合に何かが返されるかどうかを確認します。最初に無効な応答をnetcatに入力してください。エラーがスローされない場合は、PHPパッケージが作成されています。

(「tcp:// ..」ハンドルを介して通信を試みることもできます。)

次は、httpストリームラッパーパラメータの実験です。文字通り http://example.com/ を使用します。これは機能することが知られており、ユーザーエージェントをブロックすることはありません。

$context = stream_context_create(array("http"=>array(
    "method" => "GET",
    "header" => "Accept: xml/*, text/*, */*\r\n",
    "ignore_errors" => false,
    "timeout" => 50,
));

print file_get_contents("http://www.example.com/", false, $context, 0, 1000);

ignore_errorsはここで非常に関連があると思います。しかし http://www.php.net/manual/en/context.http.php をチェックして、特にprotocol_version to 1.1(チャンクされ、誤って解釈されますが、少なくともanythingが返されるかどうかを確認します)。

これでもうまくいかない場合は、httpラッパーをハックしてみてください。

<?php
    ini_set("user_agent" , "Mozilla/3.0\r\nAccept: */*\r\nX-Padding: Foo");

これにより、User-Agentが設定されるだけでなく、追加のヘッダーが挿入されます。 httpストリームラッパー内のリクエストの構築に処理上の問題がある場合、これは最終的にそれをキャッチする可能性があります。

それ以外の場合は、Zend拡張機能、Suhosin、PHP xdebug、APCおよびその他のコアモジュール)を無効にしてみてください。干渉が発生している可能性があります。そうでない場合、これはFedoraパッケージに固有の潜在的な問題です。新しいバージョンを試して、それがシステムに残っているかどうかを確認してください。

16
mario

Httpストリームラッパーを使用すると、PHPが配列を作成します _$http_response_header_ の後にfile_get_contents()(または他の任意のf関数のファミリー)が呼び出されます。これには、応答の状態に関する有用な情報が含まれています。この配列のvar_dump()を実行して、応答に関する詳細情報があるかどうかを確認できますか?

これは、本当に奇妙なエラーです。私が考えることができる唯一のことは、サーバー上の他の何かがPHPからのhttpリクエストをブロックしているということですが、それでもcURLがまだ問題ない理由がわかりません...

5
Jeremy

HttpストリームがPHPインストールに登録されていますか?phpinfo()出力で「Registered PHP Streams」を探します。鉱山は "https, ftps, compress.zlib, compress.bzip2, php, file, glob, data, http, ftp, phar, Zip "。

httpがない場合は、allow_url_fopenオンphp.ini

2