以下のサイトのサンプルを自前の環境で実行しようとしました。
https://note.com/kazztech/n/ndb3a5468f299
呼び出しプログラムを実行したところ、以下のエラーになりました。
PHP Warning: file_get_contents(http://192.168.33.10:8000/api.php?num=10): failed to open stream: HTTP request failed!
このURL自体(以下URL)は表示できました。
http://192.168.33.10:8000/api.php?num=10
結果として、{ "status": "yes", "x114": "1140", "x514": "5140" }と表示されました。
なぜエラーになるのでしょうか?
検索したところ、php.iniのallow_url_fopenの値の問題かもしれないとありましたが、これはOnでした。
WebサーバーはPHPのビルトインサーバーです。
PHPは7.1.33です。
補足1
絶対URLがうまく動いていないのかと思い、簡単なHTMLを試してみました。
<html>
<head>
<meta charset="utf-8">
<title>Absolute URL</title>
</head>
<body>
<a href="http://192.168.33.10:8000/abso.html">test</a>
</body>
</html> ```
普通にうごきます。(abso.htmlに飛ばされました)
補足2
本丸のapi.phpにしてみました。
```<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Absolute URL</title>
</head>
<body>
<a href="http://192.168.33.10:8000/api.php">test</a>
</body>
</html>```
{ "status": "no" }と表示されました。(api.phpに飛ばされました)
↓
絶対URLやapi.phpは問題ではなさそうです。
補足3
```<?php
$data = file_get_contents("http://yahoo.co.jp/");
echo $data;```
これだとうまくいく。(yahooが表示される)けど・・・
```<?php
$data = file_get_contents("http://192.168.33.10:8000/api.php");
echo $data;```
これだとダメ。
file_get_contentsは普通に動いているのだけど、PHPビルトインサーバーを指定したときはうまく動かないということなのかな・・・
補足4
こんな記事に行き当たった。
file_get_contents() で HTTP経由でデータを取得しようとしてエラーになったとき
https://qiita.com/matsuoshi/items/60a3240d0667272e0336
相手によってうまくいったり、いかなかったりしたというもの。
yahooはうまくいくけど、自前はうまくいかないというのはそっくり。
ただ、残念なことに?allow_url_fopenはONです。
しかし、相手によってうまくいったり、いかなかったりすることが、自身のphp.iniを更新することで変わるのが理解できない。
セキュリティ上、変なファイルを読み込んだらいけないとかなら、うまくいったり、いかなかったりするはずもなく、うまくいかないハズだ。
補足5
こんな記事に行き当たった。
allow_url_fopenが0のサーバーで外部ファイルを取得する方法
https://masshiro.blog/php-allow-url-fopen/
```<?php
$url="http://192.168.33.10:8000/api.php";
$cp = curl_init();
/*オプション:リダイレクトされたらリダイレクト先のページを取得する*/
curl_setopt($cp, CURLOPT_RETURNTRANSFER, 1);
/*オプション:URLを指定する*/
curl_setopt($cp, CURLOPT_URL, $url);
/*オプション:タイムアウト時間を指定する*/
curl_setopt($cp, CURLOPT_TIMEOUT, 30);
/*オプション:ユーザーエージェントを指定する*/
curl_setopt($cp, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$data = curl_exec($cp);
curl_close($cp);
echo $data;```
コンソールにエラーは表示されないけど、api.phpからの返答は表示されない。
30秒待って呼び出し元とapi.phpの読み込みログが表示されるだけでした。
var_dumpしたら、bool(false)と表示された。
サーバーが原因と絞り込んでもよさそう・・・。
補足6
こんな記事に行き当たった。
PHPでURLが実際に存在するか確認する で、いろいろ勉強したのでメモ
http://blog.doli.jp/blog/2012/post473/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579906/44ea7210-ecd7-4c9e-2b4c-0c0388f56e64.png)
LocalもONでした・・・。
補足7
この記事をもとに試してみました。
https://www.sejuku.net/blog/24113
<?php
//コンテキストを設定
\$con = stream_context_create(array('http' => array('ignore_errors' => true)));
//URLを指定してレスポンスを取得する
$http = file_get_contents('http://192.168.33.10:8000/api.php', false, \$con);
//ステータスコードを取得する
\$code = substr($http_response_header[0], 9, 3);
var_dump($code);
bool(false)と表示されました。
原因が絞り込めないから絞り込めるようにしましょう。という記事なのに、残念です。
補足8
思考がハマってるっぽいので、根本から変えてみました。
絶対パスをやめて、相対パスで呼び出し。かつ、返却を簡素に。
〇呼び出し元
<?php
\$data = file_get_contents(dirname(\_\_FILE\_\_) . "/api.php");
var_dump($data);
〇api.php
<?php
print "response";
結果は、string(26) "と表示されました。ソース表示で確認すると、
string(26) "<?php
print "response";
"
こう表示されてました。
ソースがそのまま読み込まれてました。こんな仕様だとセキュリティ的におかしいと思うので、相対パスだから、こうなったのだと思います。
思考が切り替わらないという結果になりました。
補足9
そもそもの参考サイトに立ち返ってみました。
大本のサイトはapi.phpをlocalhost/api.phpとして呼び出しています。
私は192.168.33.10で呼び出しました。
VirtualBoxの呼び出し元を呼ぶときはこのアドレスで良いけど、file_get_contentsを使用するときは、このアドレスだとダメだという気がします。
かと言って、Localhostで呼べるように設定するのは大変そうです。
相対パスでは読み込めているので、相対パスありきで考えてみます。