PHP调用file_get_contents出现HTTP request failed报错如何解决
问题根因分析
- 逻辑死循环:原有逻辑中访问MyMessagesMDB.php会触发调用GetMessages.php,而GetMessages.php执行取数逻辑后又会主动POST请求回MyMessagesMDB.php,两个脚本互相调用导致请求超时,这是报错的核心原因。
- 配置问题:php.ini中
allow_url_fopen配置项未开启,会导致file_get_contents无法发起跨域HTTP请求。 - 网络限制:服务器自身可能无法访问192.168.0.102的内网地址,比如防火墙拦截、端口未开放、路由不通等。
- 逻辑冗余:两个脚本都在同一台服务器的场景下,完全不需要走HTTP请求传递数据,本地引入效率更高。
解决方案
提供两种可落地的修复方案,优先推荐第二种本地引入的方案,性能更高、稳定性更强。
方案1:修复原有HTTP调用逻辑
先修改GetMessages.php,去掉主动POST回MyMessagesMDB.php的逻辑,直接返回JSON格式的查询结果:
<?php $FirstName = ''; $LastName = ''; $Email = ''; $Subject = ''; $Message = ''; GetFromDB(); // 直接输出JSON数据供调用方获取 echo json_encode([ 'FirstName' => $FirstName, 'LastName' => $LastName, 'Email' => $Email, 'Subject' => $Subject, 'TextMessage' => $Message ]); function GetFromDB(){ $client = new MongoDB\Driver\Manager('mongodb+srv://####:####@####.tldyu.mongodb.net/Data'); $filter = []; $options = []; $query = new MongoDB\Driver\Query($filter, $options); $cursor = $client->executeQuery('ContactMessages.ContactForm', $query); foreach($cursor as $document){ $document = json_decode(json_encode($document),true); global $FirstName, $LastName, $Email, $Subject, $Message; $FirstName = $document['FirstName']; $LastName = $document['LastName']; $Email = $document['Email']; $Subject = $document['Subject']; $Message = $document['Message']; } } ?>
再修改MyMessagesMDB.php,用兼容性更强的cURL调用GetMessages.php,直接解析返回的JSON结果即可:
<?php // 用cURL调用GetMessages.php,替代file_get_contents $curl_handle = curl_init(); curl_setopt($curl_handle, CURLOPT_URL, 'http://192.168.0.102/test/GetMessages.php'); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl_handle, CURLOPT_USERAGENT, 'PHP Local Script'); // 如果是HTTPS地址可添加以下两行跳过证书校验 curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false); $response = curl_exec($curl_handle); // 排查错误时可开启以下代码打印cURL错误 // if(curl_errno($curl_handle)){ // echo 'cURL错误信息:' . curl_error($curl_handle); // } curl_close($curl_handle); $data = json_decode($response, true) ?? []; $FirstName = $data["FirstName"] ?? ""; $LastName = $data["LastName"] ?? ""; $Email = $data["Email"] ?? ""; $Subject = $data["Subject"] ?? ""; $Message = $data["TextMessage"] ?? ""; echo $FirstName." ".$LastName; echo "<br>"; echo $Email; echo "<br>"; echo $Subject; echo "<br>"; echo $Message; echo "<br>"; ?>
方案2:本地文件引入(推荐)
两个脚本在同一台服务器的场景下,直接引入文件调用方法即可,完全避免网络请求的各类问题:
首先修改GetMessages.php,封装成可直接返回数据的函数,去掉多余的输出和HTTP请求逻辑:
<?php function GetMessageFromDB(){ $client = new MongoDB\Driver\Manager('mongodb+srv://####:####@####.tldyu.mongodb.net/Data'); $filter = []; $options = []; $query = new MongoDB\Driver\Query($filter, $options); $cursor = $client->executeQuery('ContactMessages.ContactForm', $query); $result = []; foreach($cursor as $document){ $document = json_decode(json_encode($document),true); $result = [ 'FirstName' => $document['FirstName'], 'LastName' => $document['LastName'], 'Email' => $document['Email'], 'Subject' => $document['Subject'], 'TextMessage' => $document['Message'] ]; // 如果只需要取最新一条数据可打开下方break,避免遍历后变量被覆盖 // break; } return $result; } ?>
再修改MyMessagesMDB.php,直接引入文件调用函数拿数据:
<?php // 注意替换为你服务器上GetMessages.php的实际路径 include_once './GetMessages.php'; $data = GetMessageFromDB(); $FirstName = $data["FirstName"] ?? ""; $LastName = $data["LastName"] ?? ""; $Email = $data["Email"] ?? ""; $Subject = $data["Subject"] ?? ""; $Message = $data["TextMessage"] ?? ""; echo $FirstName." ".$LastName; echo "<br>"; echo $Email; echo "<br>"; echo $Subject; echo "<br>"; echo $Message; echo "<br>"; ?>
额外排查项
如果坚持使用HTTP调用的方式,可先确认以下配置是否正常:
- 检查php.ini配置中
allow_url_fopen = On,修改后需重启web服务生效 - 登录服务器执行
curl http://192.168.0.102/test/GetMessages.php测试网络连通性 - 检查服务器防火墙、安全组是否放行内网80端口的访问请求
内容的提问来源于stack exchange,提问作者Mike Aelbrecht
相关产品推荐
相关产品推荐

