2010-08-14 30 views
3

我正在使用curl和php来查找关于给定url的信息(例如http状态码,mimetype,http重定向位置,页面标题等)。防止curl生成较大文件的致命错误

 
$ch = curl_init($url); 
$useragent="Mozilla/5.0 (X11; U; Linux x86_64; ga-GB) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.307.11 Safari/532.9"; 
curl_setopt($ch,CURLOPT_HTTPHEADER,array (
     "Accept: application/rdf+xml;q=0.9, application/json;q=0.6, application/xml;q=0.5, application/xhtml+xml;q=0.3, text/html;q=0.2, */*;q=0.1" 
    )); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_USERAGENT, $useragent); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$content=curl_exec($ch); 
$chinfo = curl_getinfo($ch); 
curl_close($ch); 

这通常效果很好。但是,如果url指向一个更大的文件,那么我会得到一个致命错误:

Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 14421576 bytes)

有没有办法防止这种情况发生?例如,通过告诉curl放弃文件是否太大或通过捕获错误?

作为一种变通方法,我已经添加

curl_setopt($ CH,CURLOPT_TIMEOUT,3); ,它假定任何加载时间超过3秒的文件将耗尽允许的内存,但这远远不能令人满意。

回答

2

您是否尝试过使用CURLOPT_FILE将文件直接保存到磁盘而不是使用内存?你甚至可以指定/dev/null将它放在任何地方......

或者,您可以使用CURLOPT_WRITEFUNCTION来设置自定义数据写入功能。让函数只扫描标题,然后丢弃实际的数据。

另外,通过php.ini给PHP一些更多的内存。

0

如果您正在获取标题信息,那么为什么不使用HEAD请求?这可以避免将整个页面放入最大16MiB内存插槽的内存使用情况。

curl_setopt($ch, CURLOPT_HEADER, true); 

然后,网页标题,使用file_get_contents()代替,因为这是其本机内存分配要好得多。

+0

最初我使用了这个解决方案,但是我发现有些网站(例如Amazon)不接受HEAD请求。 – lucas 2010-08-14 01:24:41