您的位置:首页 > 编程语言 > PHP开发

PHP下通过file_get_contents()方法不能正常获取远程网页内容

2017-06-20 15:13 1116 查看
这两天,公司的一个客户的旧汽车系统里的车库不能更新,我通过断点打印发现是一个方法获取远程网页内容失败,开始怀疑是一个自定义封装好的方法出错。在咨询老员工后,我果断替换为file_get_contents()方法执行。可是,神奇的事情发生了,开始刷新页面成功获取到远程网页内容,但是在接下来几次重复测试后,发现依旧获取远程网页内容失败……于是按着老员工的意思,探索服务器对file_get_contents()设置限制的问题。

首先,检查服务器的PHP是否支持访问URL对象(例如文件)。通过找到PHP的配置文件php.ini,把allow_url_fopen设置为On,即allow_url_fopen = On。可是,经过检查发现,客户的服务器已经激活了URL形式的fopen封装协议。

接着,继续百度寻找服务器限制file_get_contents()的解决方法。(刚刚得知程序猿是不要使用百度的,都是翻墙使用google。。。具体原因嘛,或许百度的确找到的大多是无用的信息。小弟不才,请容我先学会翻越伟大的GFW[GREAT FIRE WALL]。)于是乎,我找到了都是使用curl替代file_get_contents()的方法,大概如下:

许多作为虚拟主机出租的服务器,一般都会把file_get_contents、fsockopen等一些IO操作的函数禁用掉,因为它们怕被 DDOS。但是许多站长有需要用到这种函数来抓取URL页面内容,比如说我需要抓取各大网站UED博客里的RSS内容,输出到我的首页。那么一般情况下,我们改不了服务器的 inc.php,只能自己写一套IO来代替上面的PHP函数了。

$url = file_get_contents('http://www.chongqingwangzhai.com/');


我们可以用下面的代码代替

//禁用file_get_contents的解决办法
$ch = curl_init();
$timeout = 10; // set to zero for no timeout
curl_setopt ($ch, CURLOPT_URL,'http://www.chongqingwangzhai.com/');
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$url = curl_exec($ch);


curl是一个利用URL语法规定来传输文件和数据的工具,支持很多协议,如HTTP、FTP、TELNET等,它不会被服务器禁用,所以我们可以用来模拟file_get_contents一样打开一条URL。

而一般我们要抓取页面数据,例如新浪微博、百度论坛等得页面,都需要登录状态下才能进入列表页面,所以这个时候就需要用curl模拟登录,再打开URL,原理就是利用curl设置http访问的头部信息,模拟登录的头部信息,让对方服务器认为你是在登录状态。具体实现方法就不说了,网上很多。

(参考网址:http://blog.csdn.net/pengyouchuan/article/details/7205440

但是,根据以上方法替换后,结果依旧失败!

后来,怀疑是服务器防火墙限制。偶尔发现,通过ping有关网址出现部分ping失败的情况。据了解,有可能是服务器DNS解析有问题。网上有网友提到,通过修改/etc/hosts文件来解决问题。不过,我还是先了解一下hosts文件及其作用:

/etc/hosts,主机名和ip配置文件。

hosts—The static table lookup for host name(主机名查询静态表)

我们知道在网络上访问网站,要首先通过DNS服务器把网络域名(www.XXXX.com)解析成XXX.XXX.XXX.XXX的IP地址后,我们的计算机才能访问。要是对于每个域名请求我们都要等待域名服务器解析后返回IP信息,这样访问网络的效率就会降低,而Hosts文件就能提高解析效率。根据Windows系统规定,在进行DNS请求以前,Windows系统会先检查自己的Hosts文件中是否有这个地址映射关系,如果有则调用这个IP地址映射,如果没有再向已知的DNS 服务器提出域名解析。也就是说Hosts的请求级别比DNS高。

所以,我们可以通过事先在Hosts文件中配置好对应的地址映射关系,从而达到一系列效果。比如:1、加快域名解析;2、方便局域网用户;3、屏蔽网站;4、顺利连接系统;等等。

(参考网址:http://blog.sina.com.cn/s/blog_6714fba701018pip.html

(参考网址:http://blog.sina.com.cn/s/blog_6714fba701018pip.html

根据以上的方法,我把远程车库(目标服务器)的IP地址等信息配置到客户服务器的Hosts文件里面,刷新网站,重新点击测试功能。

远程网页内容获取成功!!!

经过多次刷新测试,系统依旧能正常获取远程网页内容!至此,“PHP下通过file_get_contents()方法不能正常获取远程网页内容”这个问题基本解决。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: