php函数file_get_contents(一)

早在2010年时候遇到过这样的事情,因为file_get_contents函数造成服务器挂掉的情况,现在觉得很有必要总结下。

公司里有经常有这样的业务,需要调用第三方公司提供的HTTP接口,在把接口提供的信息显示到网页上,代码是这样写的: file_get_contents("http://example.com/") 。
有一天突然接到运维同事的报告,说是服务器挂了,查出原因说是因为file_get_contents函数造成的,那么为什么一个函数会把服务器给搞挂掉呢?
经过详细的查询发现第三方公司提供接口已经坏掉了,就是因为接口坏掉了,才导致服务器挂掉。
问题分析如下:
    我们代码是“file_get_contents("http://example.com/") “获取一个 URL 的返回内容,如果第三方公司提供的URL响应速度慢,或者出现问题,我们服务器的PHP程序将会一直执行去获得这个URL,我们知道,在 php.ini 中,有一个参数 max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件中的以下参数: <value name="request_terminate_timeout">0s</value>   默认值为 0 秒,也就是说,PHP 脚本会一直执行下去,当请求越来越多的情况下会导致php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。CPU的利用率达到100% ,时间一长服务器就会挂掉。
问题的解决:
     已经找到问题,那么我们该怎么解决呢?
     当时想到的解决问题的办法就是设置PHP的超时时间,用set_time_limit; 设置超时时间,这样就不会卡住了。代码上线后发现服务器还是会挂掉,好像根本不起作用。后来查了资料才知道,set_time_limit设置的是PHP程序的超时时间,而不是file_get_contents函数读取URL的超时时间。set_time_limit和修改php.ini文件里max_execution_time  效果是一样的。
要设置file_get_contents函数的超时时间,可以用resource $context的timeout参数,代码如下:
1 $opts = array(
2   'http'=>array(
3     'method'=>"GET",
4     'timeout'=>10,
5   )
6 );
7 $context = stream_context_create($opts);
8 $html =file_get_contents('http://www.example.com', false, $context);
9 echo $html;

代码中的timeout就是file_get_contents读取url的超时时间。

另外还有一个说法也可以改变读取url的超时时间,就是修改php.ini中的default_socket_timeout的值,或者 ini_set('default_socket_timeout',    10);  但是我没有测试过不知道行不行。
有了解决方法之后,服务器就不会挂掉了。
在解决的过程中我还发现起到关键作用的是stream_context_create方法,里面method 可以是GET,那么能否可以POST呢?还有没有其他的参数?
还有一个为老同事告诉我们还有一个比file_get_contents更好的办法,就是用CURL。
请看下面两篇。

转载于:https://www.cnblogs.com/scofi/articles/3607529.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值