PHP實(shí)現(xiàn)的帶超時(shí)功能get_headers函數(shù)
代碼比較多,但是比較簡(jiǎn)單,一眼就看穿的,so,文字盡量少寫(xiě)了。
因?yàn)楸娝苤木W(wǎng)絡(luò)原因,gavatar也開(kāi)始越來(lái)越慢,寫(xiě)了一個(gè)小東西來(lái)解決這個(gè)問(wèn)題,過(guò)程中遇到了get_headers這個(gè)函數(shù),甚是憂傷,記錄下來(lái),以免后來(lái)人踩坑。
更新記錄,函數(shù)稍微改了一下,返回值基本和之前序列化后的結(jié)果一致,暫時(shí)沒(méi)考慮支持子項(xiàng)也支持?jǐn)?shù)組等(考慮細(xì)節(jié)性能,還想把沒(méi)用的http頭砍掉….)
需求很簡(jiǎn)單:獲取圖片的head信息。
調(diào)試程序的時(shí)候發(fā)現(xiàn)這個(gè)函數(shù)的調(diào)用很緩慢,即使綁定ip,有時(shí)候都能蹦到20多秒。
尋思這個(gè)事情還是該加個(gè)超時(shí)吧,但是看官方文檔,給出的導(dǎo)出函數(shù)接口如下:
array get_headers(string$url[,int$format=0])
你沒(méi)有看錯(cuò),這個(gè)東西沒(méi)有超時(shí)接口…
上github翻看源碼,期望可以用他的底層實(shí)現(xiàn)來(lái)重新實(shí)現(xiàn)一套:
地址 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也都沒(méi)有PHP版的導(dǎo)出函數(shù)。
于是造輪子開(kāi)始:
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;
}
對(duì)比最后結(jié)果:
原版又是蠻長(zhǎng)的等待,不知道校驗(yàn)啥去了(沒(méi)繼續(xù)追代碼了,有興趣的童鞋可以去跟下玩):
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
)
輪子版返回(瞬間返回,兩者內(nèi)容略有不同,你仔細(xì)看就能發(fā)現(xiàn)一些有趣的地方了):
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 session_start()關(guān)于Cannot send session cache limiter - headers already sent錯(cuò)誤解決方法
- php 模擬get_headers函數(shù)的代碼示例
- 使用php get_headers 判斷URL是否有效的解決辦法
- php中g(shù)et_headers函數(shù)的作用及用法的詳細(xì)介紹
- PHP提示Cannot modify header information - headers already sent by解決方法
- PHP錯(cuò)誤Warning: Cannot modify header information - headers already sent by解決方法
- PHP使用get_headers函數(shù)判斷遠(yuǎn)程文件是否存在的方法
- PHP getallheaders無(wú)法獲取自定義頭(headers)的問(wèn)題
相關(guān)文章
Smarty模板類(lèi)內(nèi)部原理實(shí)例分析
這篇文章主要介紹了Smarty模板類(lèi)內(nèi)部原理,結(jié)合實(shí)例形式模擬Smarty模板類(lèi)的定義與應(yīng)用,需要的朋友可以參考下2019-07-07phpexcel導(dǎo)入excel數(shù)據(jù)使用方法實(shí)例
phpexcel導(dǎo)入excel數(shù)據(jù)使用方法,大家參考使用吧2013-12-12ThinkPHP開(kāi)發(fā)--使用七牛云儲(chǔ)存
本文是thinkphp開(kāi)發(fā)系列文章中關(guān)于使用七牛云儲(chǔ)存的方法和具體實(shí)例,非常的簡(jiǎn)單,有需要的小伙伴可以參考下2017-09-09php 創(chuàng)建以UNIX時(shí)間戳命名的文件夾(示例代碼)
這篇文章主要介紹了php創(chuàng)建以UNIX時(shí)間戳命名的文件夾(示例代碼)。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-03-03ci檢測(cè)是ajax還是頁(yè)面post提交數(shù)據(jù)的方法
這篇文章主要介紹了ci檢測(cè)是ajax還是頁(yè)面post提交數(shù)據(jù)的方法,以PHP的環(huán)境變量為基礎(chǔ)實(shí)例展示了針對(duì)CI框架配置文件的修改技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-11-11使用Git實(shí)現(xiàn)Laravel項(xiàng)目的自動(dòng)化部署
這篇文章主要介紹了使用Git實(shí)現(xiàn)Laravel項(xiàng)目的自動(dòng)化部署,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11PHP、Python和Javascript的裝飾器模式對(duì)比
這篇文章主要介紹了PHP、Python和Javascript的裝飾器模式對(duì)比,修飾模式(Decorator Pattern),又叫裝飾者模式,是面向?qū)ο缶幊填I(lǐng)域中,一種動(dòng)態(tài)地往一個(gè)類(lèi)中添加新的行為的設(shè)計(jì)模式,需要的朋友可以參考下2015-02-02