PHP实现的带超时功能get_headers函数


Posted in PHP onFebruary 10, 2015

代码比较多,但是比较简单,一眼就看穿的,so,文字尽量少写了。
因为众所周知的网络原因,gavatar也开始越来越慢,写了一个小东西来解决这个问题,过程中遇到了get_headers这个函数,甚是忧伤,记录下来,以免后来人踩坑。
更新记录,函数稍微改了一下,返回值基本和之前序列化后的结果一致,暂时没考虑支持子项也支持数组等(考虑细节性能,还想把没用的http头砍掉….)
需求很简单:获取图片的head信息。
调试程序的时候发现这个函数的调用很缓慢,即使绑定ip,有时候都能蹦到20多秒。
寻思这个事情还是该加个超时吧,但是看官方文档,给出的导出函数接口如下:

array get_headers(string$url[,int$format=0])

你没有看错,这个东西没有超时接口…
上github翻看源码,期望可以用他的底层实现来重新实现一套:
地址 https://github.com/php/php-src/blob/88ca46d92bc1c426e7c7f7313f0fd2b7dcc33cf6/ext/standard/url.c#L710
/* {{{ proto array get_headers(string url[, int format])

   fetches all the headers sent by the server in response to a HTTP request */

PHP_FUNCTION(get_headers)

{

char*url;

size_t url_len;

php_stream_context*context;

php_stream*stream;

zval*prev_val,*hdr=NULL,*h;

HashTable*hashT;

zend_long format=0;

                

if(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"s|l",&url,&url_len,&format)==FAILURE){

return;

}

 

/** 省略其他一堆... **/

}

/* }}} */

但是很不幸的是,zend_parse_parameters 和 ZEND_NUM_ARGS也都没有PHP版的导出函数。
于是造轮子开始:

functionget_url_headers($url,$timeout=10)

{

    $ch=curl_init();

 

    curl_setopt($ch,CURLOPT_URL,$url);

    curl_setopt($ch,CURLOPT_HEADER,true);

    curl_setopt($ch,CURLOPT_NOBODY,true);

    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);

    curl_setopt($ch,CURLOPT_TIMEOUT,$timeout);

 

    $data=curl_exec($ch);

    $data=preg_split('/\n/',$data);

 

    $data=array_filter(array_map(function($data){

        $data=trim($data);

        if($data){

            $data=preg_split('/:\s/',trim($data),2);

            $length=count($data);

            switch($length){

                case2:

                    returnarray($data[0]=>$data[1]);

                    break;

                case1:

                    return$data;

                    break;

                default:

                    break;

            }

        }

    },$data));

 

    sort($data);

 

    foreach($dataas$key=>$value){

        $itemKey=array_keys($value)[0];

        if(is_int($itemKey)){

            $data[$key]=$value[$itemKey];

        }elseif(is_string($itemKey)){

            $data[$itemKey]=$value[$itemKey];

            unset($data[$key]);

        }

    }

 

    return$data;

}

对比最后结果:
原版又是蛮长的等待,不知道校验啥去了(没继续追代码了,有兴趣的童鞋可以去跟下玩):

Array

(

    [0]=>HTTP/1.0302Found

    [Accept-Ranges]=>bytes

    [Cache-Control]=>max-age=300

    [Content-Type]=>Array

        (

            [0]=>text/html;charset=utf-8

            [1]=>text/html;charset=utf-8

        )

 

    [Date]=>Array

        (

            [0]=>Fri,12Dec201415:35:40GMT

            [1]=>Fri,12Dec201415:35:43GMT

        )

 

    [Expires]=>Fri,12Dec201415:40:40GMT

    [Last-Modified]=>Wed,11Jan198408:00:00GMT

    [Link]=><http://www.gravatar.com/avatar/[省略...]?s=42&d=http%3A%2F%2F[省略...]&r=G>; rel="canonical"

    [Location]=>http://i2.wp.com/[省略...]

    [Server]=>Array

        (

            [0]=>ECS(oxr/838B)

            [1]=>nginx

        )

 

    [Source-Age]=>85

    [Via]=>1.1varnish

    [X-Cache]=>302-HIT

    [X-Varnish]=>14702550881470006304

    [Content-Length]=>0

    [Connection]=>Array

        (

            [0]=>close

            [1]=>close

        )

 

    [1]=>HTTP/1.1504Gateway Timeout

)

轮子版返回(瞬间返回,两者内容略有不同,你仔细看就能发现一些有趣的地方了):

Array

(

    [0]=>HTTP/1.1302Found

    [Accept-Ranges]=>bytes

    [Via]=>1.1varnish

    [Cache-Control]=>max-age=300

    [Server]=>ECS(oxr/838B)

    [Content-Type]=>text/html;charset=utf-8

    [X-Varnish]=>14702550881470006304

    [Date]=>Fri,12Dec201420:31:02GMT

    [Location]=>http://i2.wp.com/[省略...]

    [Expires]=>Fri,12Dec201420:36:02GMT

    [Source-Age]=>85

    [Last-Modified]=>Wed,11Jan198408:00:00GMT

    [X-Cache]=>302-HIT

    [Link]=><http://www.gravatar.com/avatar/[省略...]?s=42&d=http%3A%2F%2F[省略...]&r=G>; rel="canonical"

    [Content-Length]=>0

)
PHP 相关文章推荐
简单易用的计数器(数据库)
Oct 09 PHP
php 无限级分类学习参考之对ecshop无限级分类的解析 带详细注释
Mar 23 PHP
PHP中其实也可以用方法链
Nov 10 PHP
批量去除PHP文件中bom的PHP代码
Mar 13 PHP
php curl post 时出现的问题解决
Jan 30 PHP
PHP登录环节防止sql注入的方法浅析
Jun 30 PHP
php实现高效获取图片尺寸的方法
Dec 12 PHP
php 多文件上传的实现实例
Oct 23 PHP
PHP登录(ajax提交数据和后台校验)实例分享
Dec 29 PHP
php7安装mongoDB扩展的方法分析
Aug 02 PHP
PHP通过curl获取接口URL的数据方法
May 31 PHP
thinkphp框架类库扩展操作示例
Nov 26 PHP
Laravel框架中实现使用阿里云ACE缓存服务
Feb 10 #PHP
Laravel中扩展Memcached缓存驱动实现使用阿里云OCS缓存
Feb 10 #PHP
PHP框架Laravel的小技巧两则
Feb 10 #PHP
Laravel模板引擎Blade中section的一些标签的区别介绍
Feb 10 #PHP
Laravel 5.0 发布 新版本特性详解
Feb 10 #PHP
PHP转盘抽奖接口实例
Feb 09 #PHP
PHP积分兑换接口实例
Feb 09 #PHP
You might like
全国FM电台频率大全 - 31 新疆维吾尔族自治区
2020/03/11 无线电
PHP 和 MySQL 基础教程(三)
2006/10/09 PHP
php 上一篇,下一篇文章实现代码与原理说明
2010/05/09 PHP
PHP中将网页导出为Word文档的代码
2012/05/25 PHP
php echo, print, print_r, sprintf, var_dump, var_expor的使用区别
2013/06/20 PHP
通过Email发送PHP错误的方法
2015/07/20 PHP
PHP实现的文件上传类与用法详解
2017/07/05 PHP
javascript之卸载鼠标事件的代码
2007/05/14 Javascript
JavaScript 类的定义和引用 JavaScript高级培训 自定义对象
2010/04/27 Javascript
js监听输入框值的即时变化onpropertychange、oninput
2011/07/13 Javascript
js 判断计算字符串长度/判断空的简单方法
2013/08/05 Javascript
不要使用jQuery触发原生事件的方法
2014/03/03 Javascript
JavaScript中的pow()方法使用详解
2015/06/15 Javascript
angular源码学习第一篇 setupModuleLoader方法
2016/10/20 Javascript
利用Js的console对象,在控制台打印调式信息测试Js的实现
2016/11/26 Javascript
scroll事件实现监控滚动条并分页显示(zepto.js)
2016/12/18 Javascript
JavaScript自动点击链接 防止绕过浏览器访问的方法
2017/01/19 Javascript
Node.JS文件系统解析实例详解
2017/05/15 Javascript
JS中DOM元素的attribute与property属性示例详解
2018/09/04 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
2019/08/01 Javascript
Layui 带多选框表格监听事件以及按钮自动点击写法实例
2019/09/02 Javascript
聊聊Vue中provide/inject的应用详解
2019/11/10 Javascript
vue添加自定义右键菜单的完整实例
2020/12/08 Vue.js
Vue在H5 项目中使用融云进行实时个人单聊通讯
2020/12/14 Vue.js
python在windows下实现备份程序实例
2014/07/04 Python
Python实现的双色球生成功能示例
2017/12/18 Python
widows下安装pycurl并利用pycurl请求https地址的方法
2018/10/15 Python
python RabbitMQ 使用详细介绍(小结)
2018/11/08 Python
python使用suds调用webservice接口的方法
2019/01/03 Python
Python数据可视化库seaborn的使用总结
2019/01/15 Python
css3模拟jq点击事件的实例代码
2017/07/06 HTML / CSS
HTML5 script元素async、defer异步加载使用介绍
2013/08/23 HTML / CSS
html5页面结构_动力节点Java学院整理
2017/07/10 HTML / CSS
高校自主招生自荐信
2013/12/09 职场文书
家长给老师的道歉信
2014/01/13 职场文书
2014年学校财务工作总结
2014/12/06 职场文书