如何处理 PHP 中 file_get_contents() 函数的警告?

Posted

技术标签:

【中文标题】如何处理 PHP 中 file_get_contents() 函数的警告?【英文标题】:How can I handle the warning of file_get_contents() function in PHP? 【发布时间】:2010-09-21 07:17:29 【问题描述】:

我写了一个这样的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]:失败 打开流:

我尝试了trycatch,但没有成功。

【问题讨论】:

也是一个有趣的方法:***.com/questions/6718598/… 相关:***.com/q/2002610 将 try-catch 与 set_error_handler-function 一起使用,如此处所述***.com/a/3406181/1046909 如果您从 url 中删除 http://,那么您正在本地磁盘上查找文件“www.google.com”。 这怎么能得到如此多的关注和支持。为什么要删除协议信息。即使在 2008 年,你也有 FTP 和 HTTPS。 【参考方案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 测试结果值。 这将触发不返回正文的成功请求的错误,或者返回一个评估为假的请求。应该是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';

【讨论】:

以上是关于如何处理 PHP 中 file_get_contents() 函数的警告?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 PHP 代码中的 HTTP/1.1 403 Forbidden

如何处理在 php mysql 中返回多个值的内部查询?

如何处理 PHP 请求中的长标头声明?

PHP XML RPC - 如何处理返回的数组

最佳实践:在 php-doc 中使用 @throws,以及如何处理它

Angularjs如何处理来自php(json)的二维数组