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


312

我写了这样的PHP代码

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

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

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

我试过了trycatch但是没有用。




如此处所述,将try-catch与set_error_handler-function一起使用stackoverflow.com/a/3406181/1046909
MingalevME

2
如果您从网址中删除http://,那么您正在本地磁盘上寻找文件“ www.google.com”。
Rauli Rajande

如何获得如此多的关注和支持。为什么要删除协议信息。即使在2008年,您也拥有FTP和HTTPS。
Daniel W.

Answers:


506

步骤1:检查返回码: if($content === FALSE) { // handle error here... }

步骤2:通过在调用file_get_contents()的前面放置错误控制运算符(即@)来抑制警告: $content = @file_get_contents($site);


86
记住要使用严格的比较:if($ content === FALSE)。如果文件包含“ 0”,则它将触发假否定。
Aram Kocharyan

7
嗨,这对我来说不起作用,添加@仍会导致E_WARNING被某些全局(而非我的)错误处理程序捕获,并且我的脚本在有机会处理返回值之前就死了。有任何想法吗?tnx。
Sagi Mann

1
检测到副作用:如果文件不存在,脚本将在@file_get_contents行处停止。
达克斯(Dax)

即使这将是正确的解决方案,这对我也不起作用。我有一个超时警告,没有接收到任何数据,但是$ content === FALSE没有被“触发”(从本地服务器调用$ site,请注意,如果我将自己的URL粘贴到浏览器中,我将很快得到数据)。
奥利弗

4
尽管答案很旧,但我仍然建议在答案中添加注释,@以免使用会对性能产生负面影响。请在相关的帖子中看到此答案,该帖子解释得很好。
Fr0zenFyr 2015年

148

您还可以将错误处理程序设置为调用Exception匿名函数,并对该异常使用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();

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


到目前为止,这是我最大的PHP改进之一。谢谢enobrev
Tomasz Smykowski 2012年

@enobrev,为什么为错误编号和严重性输入相同的值?
Pacerier

除了提供在$ exception-> getCode()中有用的方法外,没有其他特殊原因,因为set_error_handler不提供错误号变量(不幸的是)。
enobrev

1
@enobrev在引发异常之前,请不要忘记在匿名函数中恢复错误处理程序。可以处理异常,在这种情况下,处理程序仍设置为抛出该特定异常,这可能是意外的,并在异常处理中出现另一个错误时引入了奇怪的,难以调试的行为。
约瑟夫·萨布(JosefSábl)

1
我建议在“ finally”块中包含restore_error_handler()调用
peschanko

67

我最喜欢的方法很简单:

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

我在使用上述try/catch@enobrev 进行实验后发现了这一点,但这可以减少冗长的代码(以及IMO,更易读)。我们仅使用error_get_last获取最后一个错误的文本,并file_get_contents在失败时返回false,因此可以使用简单的“ if”来捕获该错误。


2
这是解决此问题的最简单,最佳方法!也许可以@file_get_contents阻止向浏览器报告错误。
EDP​​ 2015年

1
我承认,在所有答案中,这是唯一明智的答案-如果我们将其扩充以用于@file_get_contents抑制警告使用来测试结果值=== FALSE
kostix

11
对于不会返回正文或返回结果为false的成功请求,这将触发错误。应该是if (false !== ($data = file_get_contents ()))
GordonM '16

文档尚不清楚,但是根据error_get_last我的经验,使用@可能不会返回任何内容
Glenn Schmidt

33

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

这将禁止任何警告- 谨慎使用!。请参阅错误控制运算符

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


那是唯一真正起作用的东西-我无法以其他任何方式抑制“无法打开流”消息。
Olaf

21

一种选择是抑制错误,并引发异常,以后可以捕获该异常。如果您的代码中有多个对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();
}

15

这就是我的操作方式...不需要try-catch块...最佳解决方案始终是最简单的...享受!

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

4
-1:如果出现404错误或类似错误,此方法有效,但是如果您根本无法连接至服务器(例如,错误的域名),则无效。我认为$http_response_header在这种情况下不会更新,因为没有收到HTTP响应。
内森·里德

1
正如@NathanReed所说的,您应该检查$ content是否为false(带有===),因为如果请求完全无法连接,这就是返回的内容
2014年

15
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,则仍会出现警告。
猛禽

对了,猛禽,我用stream_context_create()改善了答案。没有比这更好的了……不推荐使用“ @”
RafaSashi

1
ignore_errors仅指示HTTP上下文不将HTTP响应状态代码> = 400解释为错误。虽然关系不大,但这不能解决PHP错误处理的问题。
太阳

感谢您的ignore_errors选择!这就是我所需要的!
Modder

6

这是我的处理方式:

$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();
}

4

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


1

您可以使用此脚本

$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或为空,则会引发连接错误。
Daniel W.

1

由于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;
}


1

像这样的东西:

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]);
}

1
if (!file_get_contents($data)) {
  exit('<h1>ERROR MESSAGE</h1>');
} else {
      return file_get_contents($data);
}

-2

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

$file = "path/to/file";

if(file_exists($file)){
  $content = file_get_contents($file);
}

仅当您调用本地文件并且您具有检查本地文件是否存在的正确权限时
这才有效


-3

这将尝试获取数据,如果它不起作用,它将捕获错误并允许您在捕获中执行所需的任何操作。

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

-3
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并不总是抛出异常
marlar

您想编辑答案并告诉我们,file_get_content在什么时候引发异常吗?
Ravinder Payal

1
尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以提高其长期价值。
杰·布兰查德

-3

您还应该设置

allow_url_use = On 

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.