【问题标题】:How can I handle the warning of file_get_contents() function in PHP?如何处理 PHP 中 file_get_contents() 函数的警告?
【发布时间】:2023-03-18 14:25:01
【问题描述】:

我写了一个这样的PHP代码

$site="http://www.google.com";
$content = file_get_content($site);
echo $content;

但是当我从$site 中删除“http://”时,我收到以下警告:

警告: file_get_contents(www.google.com) [function.file-get-contents]:失败 打开流:

我尝试了try 和catch,但没有成功。

【问题讨论】:

标签: php function exception warnings file-get-contents


【解决方案1】:

第一步:查看返回码:if($content === FALSE) { // handle error here... }

第 2 步:通过在对 file_get_contents() 的调用前面放置 error control operator(即 @)来抑制警告: $content = @file_get_contents($site);

【讨论】:

  • 记得使用严格比较: if ($content === FALSE) 。如果文件包含“0”,那么会触发漏报。
  • 嗨,这对我不起作用,添加 @ 仍然会导致 E_WARNING 被一些全局(不是我的)错误处理程序捕获,并且我的脚本在我有机会处理返回值之前就死了.有任何想法吗? tnx.
  • 检测到副作用:如果文件不存在,脚本将在@file_get_contents 行停止。
  • 这对我不起作用,即使这将是正确的解决方案。我有一个没有收到数据的超时警告,但是 $content === FALSE 没有被“触发”($site 是从本地主机服务器调用的,请注意,如果我将自己的 url 粘贴到浏览器中,我很快就会收到数据)。
  • 虽然答案已经很老了,但我仍然建议在您的答案中添加注释,说明使用 @ 可能会对性能产生负面影响。请参阅相关帖子中的this answer,该帖子解释得很好。
【解决方案2】:

您也可以将set your error handler 用作调用Exception 的anonymous function,并对该异常使用try / catch。

set_error_handler(
    function ($severity, $message, $file, $line) {
        throw new ErrorException($message, $severity, $severity, $file, $line);
    }
);

try {
    file_get_contents('www.google.com');
}
catch (Exception $e) {
    echo $e->getMessage();
}

restore_error_handler();

似乎需要很多代码来捕获一个小错误,但如果您在整个应用程序中使用异常,则只需执行一次,在顶部(例如,在包含的配置文件中),它会将你所有的错误转换为异常。

【讨论】:

  • @enobrev,为什么错误号和严重性的值相同?
  • 除了在 $exception->getCode() 中提供有用的方法之外没有具体原因,因为 set_error_handler 不提供错误编号变量(很遗憾)。
  • @lolka_bolka 因为 file_get_contents 不会抛出异常,而是会抛出 php 错误。所以这个例子所做的是设置一个“错误处理程序”,它捕获大多数被抛出的 php 错误实例,并将这些错误转换为异常。这是文档中更现代的示例:php.net/manual/en/…
  • @enobrev 不要忘记在抛出异常之前恢复匿名函数内的错误处理程序。异常可以被处理,在这种情况下,处理程序仍然设置为抛出这个可能出乎意料的特殊异常,并在异常处理中出现另一个错误时引入奇怪的、难以调试的行为。
  • 我建议在 finally 块中包含 restore_error_handler() 调用
【解决方案3】:

我最喜欢的方法很简单:

if (($data = @file_get_contents("http://www.google.com")) === false) {
      $error = error_get_last();
      echo "HTTP request failed. Error was: " . $error['message'];
} else {
      echo "Everything went better than expected";
}

我在尝试了上面@enobrev 中的try/catch 后发现了这一点,但这可以减少冗长(并且IMO,更易读)的代码。我们简单地使用error_get_last 来获取最后一个错误的文本,file_get_contents 在失败时返回 false,所以一个简单的 "if" 就可以捕捉到它。

【讨论】:

  • 这是这个问题最简单最好的解决方案!或许将其设为@file_get_contents 以抑制向浏览器报告错误。
  • 我承认,在所有答案中,这是唯一明智的答案——如果我们将其扩充为使用@file_get_contents 来抑制警告和 使用=== FALSE 测试结果值。
  • 这将为不返回正文的成功请求触发错误,或者返回评估为 false 的请求。应该是if (false !== ($data = file_get_contents ()))
  • 文档没有说清楚,但使用 @ 可能会导致 error_get_last 在我的经验中不返回任何内容
  • 第一个条件是倒退。如果 false 不等于 file_get_contents 调用的结果,那么它得到了一些内容,我们不应该寻找错误。看到之前测试的错误,或者在真正找到 google 时看到 $error 为 null 的错误,我感到很困惑!
【解决方案4】:

您可以在前面加上@: $content = @file_get_contents($site);

这将抑制任何警告 - 谨慎使用!。见Error Control Operators

编辑:删除“http://”后,您不再寻找网页,而是磁盘上名为“www.google.....”的文件

【讨论】:

  • 这是唯一真正有效的方法 - 我无法以任何其他方式抑制“无法打开流”消息。
【解决方案5】:

另一种方法是抑制错误并引发稍后可以捕获的异常。如果您的代码中有多个对 file_get_contents() 的调用,这尤其有用,因为您不需要手动抑制和处理所有这些调用。相反,可以在单个 try/catch 块中对该函数进行多次调用。

// Returns the contents of a file
function file_contents($path) {
    $str = @file_get_contents($path);
    if ($str === FALSE) {
        throw new Exception("Cannot access '$path' to read contents.");
    } else {
        return $str;
    }
}

// Example
try {
    file_contents("a");
    file_contents("b");
    file_contents("c");
} catch (Exception $e) {
    // Deal with it.
    echo "Error: " , $e->getMessage();
}

【讨论】:

    【解决方案6】:

    我是这样做的...不需要 try-catch 块...最好的解决方案总是最简单的...享受!

    $content = @file_get_contents("http://www.google.com");
    if (strpos($http_response_header[0], "200")) { 
       echo "SUCCESS";
    } else { 
       echo "FAILED";
    } 
    

    【讨论】:

    • -1:如果您收到 404 错误或其他错误,则此方法有效,但如果您根本无法连接到服务器(例如错误的域名),则无效。我认为$http_response_header 在这种情况下不会更新,因为没有收到 HTTP 响应。
    • 正如@NathanReed 所说,您应该检查 $content 是否为假(使用 ===),因为如果请求根本无法连接,这就是返回的内容
    【解决方案7】:
    function custom_file_get_contents($url) {
        return file_get_contents(
            $url,
            false,
            stream_context_create(
                array(
                    'http' => array(
                        'ignore_errors' => true
                    )
                )
            )
        );
    }
    
    $content=FALSE;
    
    if($content=custom_file_get_contents($url)) {
        //play with the result
    } else {
        //handle the error
    }
    

    【讨论】:

    • 这不起作用。如果$url是404 not found,还是会出现警告。
    • Right Raptor,我用 stream_context_create(); 改进了答案;没有比这更好的了……不推荐使用“@”
    • ignore_errors 仅指示 HTTP 上下文不将 HTTP 响应状态代码 >= 400 解释为错误。虽然关系不大,但这并不能回答 PHP 错误处理的问题。
    • 感谢ignore_errors 选项!这就是我需要的!
    【解决方案8】:

    我是这样处理的:

    $this->response_body = @file_get_contents($this->url, false, $context);
    if ($this->response_body === false) {
        $error = error_get_last();
        $error = explode(': ', $error['message']);
        $error = trim($error[2]) . PHP_EOL;
        fprintf(STDERR, 'Error: '. $error);
        die();
    }
    

    【讨论】:

      【解决方案9】:

      最好的办法是设置您自己的错误和异常处理程序,它们会做一些有用的事情,例如将其记录到文件中或通过电子邮件发送关键文件。 http://www.php.net/set_error_handler

      【讨论】:

        【解决方案10】:

        你可以使用这个脚本

        $url = @file_get_contents("http://www.itreb.info");
        if ($url) {
            // if url is true execute this 
            echo $url;
        } else {
            // if not exceute this 
            echo "connection error";
        }
        

        【讨论】:

        • 这需要严格比较:if ($url === true)...,因为如果您得到响应0 或为空,则会引发连接错误。
        【解决方案11】:

        从 PHP 4 开始使用 error_reporting():

        $site="http://www.google.com";
        $old_error_reporting = error_reporting(E_ALL ^ E_WARNING);
        $content = file_get_content($site);
        error_reporting($old_error_reporting);
        if ($content === FALSE) {
            echo "Error getting '$site'";
        } else {
            echo $content;
        }
        

        【讨论】:

          【解决方案12】:

          最简单的方法是在 file_get_contents 之前添加一个 @, 一世。 e.:

          $content = @file_get_contents($site); 
          

          【讨论】:

            【解决方案13】:

            类似这样的:

            public function get($curl,$options){
                $context = stream_context_create($options);
                $file = @file_get_contents($curl, false, $context);
                $str1=$str2=$status=null;
                sscanf($http_response_header[0] ,'%s %d %s', $str1,$status, $str2);
                if($status==200)
                    return $file        
                else 
                    throw new \Exception($http_response_header[0]);
            }
            

            【讨论】:

              【解决方案14】:
              if (!file_get_contents($data)) {
                exit('<h1>ERROR MESSAGE</h1>');
              } else {
                    return file_get_contents($data);
              }
              

              【讨论】:

              • 没有。你应该 === 进行条件检查。不是 ==
              • 不建议运行 file_get_contents 两次。一次就够了。
              【解决方案15】:

              从 cPanel 或 WHM 启用 allow_url_fopen 然后尝试希望它会修复

              【讨论】:

                【解决方案16】:

                我解决了所有问题,所有链接都可以使用

                public function getTitle($url)
                    {
                        try {
                            if (strpos($url, 'www.youtube.com/watch') !== false) {
                                $apikey = 'AIzaSyCPeA3MlMPeT1CU18NHfJawWAx18VoowOY';
                                $videoId = explode('&', explode("=", $url)[1])[0];
                                $url = 'https://www.googleapis.com/youtube/v3/videos?id=' . $videoId . '&key=' . $apikey . '&part=snippet';
                
                                $ch = curl_init();
                
                                curl_setopt($ch, CURLOPT_HEADER, 0);
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                                curl_setopt($ch, CURLOPT_URL, $url);
                                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
                                curl_setopt($ch, CURLOPT_VERBOSE, 0);
                                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                                $response = curl_exec($ch);
                                curl_close($ch);
                
                                $data = json_decode($response);
                                $value = json_decode(json_encode($data), true);
                
                                $title = $value['items'][0]['snippet']['title'];
                            } else {
                                set_error_handler(
                                    function () {
                                            return false;
                                    }
                                );
                                if (($str = file_get_contents($url)) === false) {
                                    $title = $url;
                                } else {
                                    preg_match("/\<title\>(.*)\<\/title\>/i", $str, $title);
                                    $title = $title[1];
                                    if (preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $title))
                                        $title = utf8_encode($title);
                                    $title = html_entity_decode($title);
                                }
                                restore_error_handler();
                            }
                        } catch (Exception $e) {
                            $title = $url;
                        }
                        return $title;
                    }
                

                【讨论】:

                • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
                【解决方案17】:

                您应该在使用 file_get_contents() 之前使用 file_exists() 函数。 通过这种方式,您将避免 php 警告。

                $file = "path/to/file";
                
                if(file_exists($file)){
                  $content = file_get_contents($file);
                }
                

                【讨论】:

                • 这只有在你调用一个本地文件并且你有正确的权限来检查本地文件是否存在时才有效
                【解决方案18】:
                try {
                   $site="http://www.google.com";
                   $content = file_get_content($site);
                   echo $content;
                } catch (ErrorException $e) {
                    // fix the url
                
                }
                
                set_error_handler(function ($errorNumber, $errorText, $errorFile,$errorLine ) 
                {
                    throw new ErrorException($errorText, 0, $errorNumber, $errorFile, $errorLine);
                });
                

                【讨论】:

                • file_get_content 并不总是抛出异常
                • 您想编辑您的答案并告诉我们 file_get_content 在什么时候抛出异常?
                • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
                【解决方案19】:

                你还应该设置

                allow_url_use = On 
                

                在您的php.ini 中停止接收警告。

                【讨论】:

                  【解决方案20】:

                  更改文件 php.ini

                  allow_url_fopen = On
                  
                  allow_url_include = On
                  

                  【讨论】:

                  • 不要这样做。特别是不允许包含 url。不要,相信我。默认情况下它已被禁用,原因很充分#c99。
                  【解决方案21】:

                  这将尝试获取数据,如果它不起作用,它将捕获错误并允许您在捕获中做任何您需要的事情。

                  try {
                      $content = file_get_contents($site);
                  } catch(\Exception $e) {
                      return 'The file was not found';
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 2017-10-18
                    • 1970-01-01
                    • 2011-11-27
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-03-20
                    • 2018-09-13
                    相关资源
                    最近更新 更多