ローカル環境でfile_get_contentsがタイムアウト
- 2023.01.24
- PHP
- cURL, file_get_contents, タイムアウト
はじめに
PHPの関数file_get_contents、とても手軽なのでよく使ってしまいますが、たまにうまく動いてくれない時があります。今回は取得先のURLからのレスポンスが返ってこず、タイムアウトしてしまったので、解決方法をメモしておきます。
経緯
具体的には、ローカル(docker)のPHP環境でのサイト制作で、Googleのサービス「reCAPTCHA」を実装中、判定結果を受け取るために、reCAPTCHAのAPIにfile_get_contents()した時にタイムアウトが発生。
原因
不明。いろいろ調べてみましたが、はっきりとした原因にはたどり着けませんでした。
同じコードを本番サーバ上で実行すると問題は起きないので、ローカル環境に問題がありそうですが、Google側で何かしらの規制をしているのか、はたまたfile_get_contentsの仕様の可能性も。
解決方法
原因はわからなかったものの、解決方法が2つのほどあったので載せておきます。自分はその2の方で対処しました。
その1
file_get_contentsのタイムアウト時間を設定する。
$context = stream_context_create([
'http' => [
'ignore_errors' => true,
'timeout' => 5
]
]);
$url = 'https://xxxxxx';
$res = file_get_contents($url, false, $context);
上記のようにfile_get_contentsの第3引数にコンテキストでタイムアウト時間を設定する。ignore_errorsの指定はなくても結果は変わらなかったが、エラーを無視するために一応入れてあります。
勝手な考察
多分、file_get_contents内で何らかのエラーによって処理が止まってしまっている。取得先URLからのレスポンス自体は受け取っているが、処理が止まっていて返ってこない。なのでタイムアウト設定で無理やり返させる。
タイムアウトを設定しない場合、PHP側のタイムアウト(デフォルト60s)でエラーとなる。PHP側がエラーを吐く前にfile_get_contents側でタイムアウトさせてレスポンスを受け取るという感じ。
その2
file_get_contentsはあきらめてcURLを使う。
できればfile_get_contentsで解決したかったが、根本的な解決方法がわからなかったので、素直にcurlを使うことにしました。
function file_get_contents_curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 文字列で受け取る
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
$url = 'https://xxxxxx';
$res = file_get_contents_curl($url);
file_get_contentsライクに使いたかったので自作関数を作っています。
curlにはオプションがたくさんありますが、上記のコードは最低限のオプションのみです。取得先に合わせてカスタマイズしてください。
まとめ
原因がわからずスッキリしない結果となりましたが、そもそもcurlの方が有能なのでトラブルを避けるためにも極力curlを使った方が良いのかもしれませんね。
原因・対処法わかる方がいたら教えてもらえると助かります。よろしくお願いします😅
-
前の記事
【PHP】変数の内容をファイルに書き出す(デバッグ・ログ) 2022.10.16
-
次の記事
ファイル・画像をアップロードする最低限のサンプルコード(コピペ用テンプレ) 2023.01.28
コメントを書く