Php 如何在没有PECL的情况下获得http_parse_头的功能?

Php 如何在没有PECL的情况下获得http_parse_头的功能?,php,http,Php,Http,我在windows上使用PHP5.3.5,但我没有找到任何与我的安装兼容的pecl_http.dll 所以我的问题是, 如何在不使用PECL的情况下获得的功能?从文档页面,第一条注释: if( !function_exists( 'http_parse_headers' ) ) { function http_parse_headers( $header ) { $retVal = array(); $fields = explode("

我在windows上使用PHP5.3.5,但我没有找到任何与我的安装兼容的
pecl_http.dll

所以我的问题是,


如何在不使用PECL的情况下获得的功能?

从文档页面,第一条注释:

 if( !function_exists( 'http_parse_headers' ) ) {
     function http_parse_headers( $header )
     {
         $retVal = array();
         $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header));
         foreach( $fields as $field ) {
             if( preg_match('/([^:]+): (.+)/m', $field, $match) ) {
                 $match[1] = preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("\0")', strtolower(trim($match[1])));
                 if( isset($retVal[$match[1]]) ) {
                     $retVal[$match[1]] = array($retVal[$match[1]], $match[2]);
                 } else {
                     $retVal[$match[1]] = trim($match[2]);
                 }
             }
         }
         return $retVal;
     }
}
如果(!function_存在('http_parse_headers')){
函数http_parse_头($header)
{
$retVal=array();
$fields=explode(“\r\n”,preg_replace('/\x0D\x0A[\x09\x20]+/','','',$header));
foreach($fields作为$field){
if(preg_match('/([^::]+):(.+)/m',$field,$match)){

$match[1]=preg_replace('/(?您可以在

这是一个
php_http-5.3-*-x86.zip
文件。检查您安装的php并选择正确的,例如,我的php是一个php-5.3.6-nts-Win32-VC9-x86,所以我需要php_http-5.3-nts-SVN2009-1125-VC9-x86.zip

下载zip文件并将php_http.dll解压缩到扩展文件夹中。扩展文件夹应该是php安装目录中的/ext文件夹。如果不确定,请打开php.ini文件并搜索以下行:

; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
; extension_dir = "./"
; On windows:
extension_dir = .\ext
extension_dir的值是必须放置dll的位置。如果不确定php.ini的位置,请打开命令提示符并执行以下操作

php --ini
这将告诉您php.ini的位置

Configuration File (php.ini) Path: C:\Windows
Loaded Configuration File:         C:\php5\php-5.3.6-nts-Win32-VC9-x86\php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)
;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
复制dll后,将扩展添加到php.ini以启用它

Configuration File (php.ini) Path: C:\Windows
Loaded Configuration File:         C:\php5\php-5.3.6-nts-Win32-VC9-x86\php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)
;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
应该有多行类似于此:

;extension=php_sybase_ct.dll
extension=php_tidy.dll
;extension=php_xmlrpc.dll
extension=php_xsl.dll
;extension=php_zip.dll
添加以下行:

extension=php_http.dll
保存php.ini并在命令提示符下键入以下内容:

php --ri http
您现在应该得到一个相当广泛的输出,从

http
HTTP Support => enabled
Extension Version => 1.7.0-dev
… more stuff
这意味着您已经成功安装了扩展,现在可以使用它了


请注意,为了能够在Windows上加载此扩展,您还需要加载以下PHP扩展:哈希、iconv和SPL。

这里是文档页面的一个修改版本,其工作方式与PECL版本相同:)

函数http\u parse\u头($header){
$retVal=array();
$fields=explode(“\r\n”,preg_replace('/\x0D\x0A[\x09\x20]+/','','',$header));
foreach($fields作为$field){
if(preg_match('/([^::]+):(.+)/m',$field,$match)){

$match[1]=preg_replace('/(?不幸的是,对于文档页中提供的函数,如果有两个以上的相同标头(即Set Cookie),数组的结构将不正确,例如:

    [Set-Cookie] => Array
    (
        [0] => Array
        (
            [0] => AWESOMESESSIONID=xQ5TRl1GXDQcQCXytfb1PK!-744872953!NONE; Path=/cte-lps2s-test2/; Secure
            [1] => AWESOME_SESSH_c25c28d0-b763-11df-979f23a029aa77=%2Fcte-lps2s-test2; Path=/
        ) 
        [1] => MOREAWESOME=2_uGgNpo2-jm-CjfaefLzjFhmmP-y3HzwNZKE0gsTeP+; Path=/; Secure
    )
下面对代码的修改将修复此错误(请参阅注释):

如果(!function_存在('http_parse_headers')){
函数http_parse_头($header)
{
$retVal=array();
$fields=explode(“\r\n”,preg_replace('/\x0D\x0A[\x09\x20]+/','','',$header));
foreach($fields作为$field){
if(preg_match('/([^::]+):(.+)/m',$field,$match)){

$match[1]=preg_replace('/(?这也是从中提出来的。当我将它与的答案(使用
microtime
)进行比较时,我发现使用10个标题的样本(大概是因为它不使用正则表达式)平均快17%

注意:这包括作者在后面的评论中指出的修正


正则表达式函数

0.00035881996
0.00036096572
0.00034999847
0.0004397492
0.00033497810

平均值:0.000368547434

此功能

0.00006198883
0.00006604194
0.00007104873
0.00006413459
0.00006389617

平均0.000065422052


我不想继续这样一条已经很长的老线索,但这条线索更优越,因为:

  • 不使用regexp
  • 正确处理重复的标题
  • 没有那么多数组和字符串变异调用
  • 解析状态行
(您可能需要代码来检查扩展是否已经存在)


因为我曾经找不到任何与PECL完全相同的函数,所以我编写了自己的函数,与其他函数相比,它的速度非常快

function dirtyHeaderParser($headers, $strict = true){
    $arr = array();
    $s = strtok($headers, ':');
    while ($s){
        if ( ($s[0] === ' ') || ($s[0] === "\t") ){
            if (count($arr) != 0){
                $tail = strtok('');
                $tail = "{$s}:{$tail}";
                $v = strtok($tail, "\n");
                if (is_array($arr[$key])){
                    end($arr[$key]);
                    $last = key($arr[$key]);
                    $arr[$key][$last] = "{$arr[$key][$last]}\n{$v}";
                    reset($arr[$key]);
                } else {
                    $arr[$key] = "{$arr[$key]}\n{$v}";
                }
            }
        } else {
            $v = strtok("\n");
            if ($v){
                $key = strtolower($s);
                if (((strpos($key, "\n") !== false) || (strpos($key, "\t") !== false) || (strpos($key, " ") !== false)) && $strict) {
                    return false;
                } 
                if (array_key_exists($key, $arr)){
                    if (!is_array($arr[$key])){
                        $arr[$key] = array($arr[$key]);
                    }
                    $arr[$key][] = trim($v);
                } else {
                    $arr[$key] = trim($v);
                }
            } else {
                break;
            }
        }
        $s = strtok(':');
    }
    return (count($arr) == 0) ? false : $arr;
}
严格模式意味着,如果标题键包含
\n
、空格或
\t
,它将返回
false

它支持多行标题和双标题值(也支持多行),如果有人发现某些行为与PECL版本不一样,我很乐意您发表评论。

不,我也没有visual studio,以防您要求我构建它:(使用curl。[这是一个工作片段][1]替换httpRequest的代码的集合。[1]:保持线程打开,只是为了看看是否有其他建议……哦,等等,我也看到了:“它可能没有PECL版本那么健壮,因为它只在头以换行符(\n)分隔的情况下进行分析。”在同一页中!!:(@Shrinath这是另一个例子,因此不适用于此函数。您是否真的尝试过使用它?它认为它实际上与http_parse_头的工作原理相同,尽管它可能有点不同。@Berry Langerak:对不起,伙计,@Gordon家伙把它作为链接:)这实际上解决了我的目的,尽管这不是真正的问题。@Shrinath别担心。:)如果这对你有帮助,它对你也有帮助!(1)Hash,iconv,SPL->我不知道它们是什么,我没有做任何事。(2)它起作用了:)我不知道那个链接。只是需要下载所需的dll并做扩展部分。Thanks@ShrinathHash、Iconv和SPL是额外的扩展。IIRC它们在PHP5.3中默认启用,所以这就是为什么您不必对它们做任何事情。我只是觉得我应该注意它的完整性。我喜欢“注意它的完整性”部分:)谢谢:)我需要你的帮助,在我安装了dll之后,apache一直告诉我:php5。
function parse_headers($headers)
{
    $headers = preg_replace('/^\r\n/m', '', $headers);
    $headers = preg_replace('/\r\n\s+/m', ' ', $headers);
    preg_match_all('/^([^: ]+):\s(.+?(?:\r\n\s(?:.+?))*)?\r\n/m', $headers . "\r\n", $matches);

    $result = array();
    foreach ($matches[1] as $key => $value)
        $result[$value] = (array_key_exists($value, $result) ? $result[$value] . "\n" : '') . $matches[2][$key];

    return $result;
}
function dirtyHeaderParser($headers, $strict = true){
    $arr = array();
    $s = strtok($headers, ':');
    while ($s){
        if ( ($s[0] === ' ') || ($s[0] === "\t") ){
            if (count($arr) != 0){
                $tail = strtok('');
                $tail = "{$s}:{$tail}";
                $v = strtok($tail, "\n");
                if (is_array($arr[$key])){
                    end($arr[$key]);
                    $last = key($arr[$key]);
                    $arr[$key][$last] = "{$arr[$key][$last]}\n{$v}";
                    reset($arr[$key]);
                } else {
                    $arr[$key] = "{$arr[$key]}\n{$v}";
                }
            }
        } else {
            $v = strtok("\n");
            if ($v){
                $key = strtolower($s);
                if (((strpos($key, "\n") !== false) || (strpos($key, "\t") !== false) || (strpos($key, " ") !== false)) && $strict) {
                    return false;
                } 
                if (array_key_exists($key, $arr)){
                    if (!is_array($arr[$key])){
                        $arr[$key] = array($arr[$key]);
                    }
                    $arr[$key][] = trim($v);
                } else {
                    $arr[$key] = trim($v);
                }
            } else {
                break;
            }
        }
        $s = strtok(':');
    }
    return (count($arr) == 0) ? false : $arr;
}
function parse_headers($headers)
{
    $headers = preg_replace('/^\r\n/m', '', $headers);
    $headers = preg_replace('/\r\n\s+/m', ' ', $headers);
    preg_match_all('/^([^: ]+):\s(.+?(?:\r\n\s(?:.+?))*)?\r\n/m', $headers . "\r\n", $matches);

    $result = array();
    foreach ($matches[1] as $key => $value)
        $result[$value] = (array_key_exists($value, $result) ? $result[$value] . "\n" : '') . $matches[2][$key];

    return $result;
}