我正在编写一个通过套接字与SMTP服务器通信的脚本,我正在尝试实现DIGEST-MD5身份验证,但是我在解析后发回的字符串时遇到了问题AUTH命令。</ p>
看似base64_decode()
之后:
realm="smtp.domain.net",nonce="AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=",qop="auth,auth-int",charset=utf-8,algorithm=md5-sess
我想使用str_getcsv()
,但是服务器仍然在PHP 5.2上,所以我得到了以下代码from the comments on PHP.net,它看起来很好:
<?php
if (!function_exists('str_getcsv')) {
function str_getcsv($input, $delimiter=',', $enclosure='"', $escape=null, $eol=null) {
$temp=fopen("php://memory", "rw");
fwrite($temp, $input);
fseek($temp, 0);
$r = array();
while (($data = fgetcsv($temp, 4096, $delimiter, $enclosure)) !== false) {
$r[] = $data;
}
fclose($temp);
return $r;
}
}
但它返回以下内容:
array (
0 =>
array (
0 => 'realm="smtp.domain.net"',
1 => 'nonce="2PuESkmrNzGu/5b8N6eIYQoW7mSlScnYAB/PSYebkYo="',
2 => 'qop="auth',
3 => 'auth-int"',
4 => 'charset=utf-8',
5 => 'algorithm=md5-sess',
),
)
请注意,索引2和3应该是单个qop="auth,auth-int"
。
在写这篇文章时,我意识到可能fgetcsv()
期望$enclosure
字符包含整个字段而不仅仅是其中的一部分,但在这种情况下我必须知道如何正确地解析这个字符串。
答案 0 :(得分:0)
在我的'PHP DIGEST-MD5'的谷歌搜索中,我遇到a patch for another project处理相同格式的字符串与下面的行:
preg_match_all('/(\w+)=(?:"([^"]*)|([^,]*))/', $challenge, $matches);
这给了我:
array (
0 =>
array (
0 => 'realm="smtp.domain.net',
1 => 'nonce="AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=',
2 => 'qop="auth,auth-int',
3 => 'charset=utf-8',
4 => 'algorithm=md5-sess',
),
1 =>
array (
0 => 'realm',
1 => 'nonce',
2 => 'qop',
3 => 'charset',
4 => 'algorithm',
),
2 =>
array (
0 => 'smtp.domain.net',
1 => 'AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=',
2 => 'auth,auth-int',
3 => '',
4 => '',
),
3 =>
array (
0 => '',
1 => '',
2 => '',
3 => 'utf-8',
4 => 'md5-sess',
),
)
然后我可以用这个循环填写一个有用的数组:
$authvars = array();
foreach( $auth_matches[1] as $key => $val ) {
if( !empty($auth_matches[2][$key]) ) {
$authvars[$val] = $auth_matches[2][$key];
} else {
$authvars[$val] = $auth_matches[3][$key];
}
}
这给了我:
array (
'realm' => 'ns103.zabco.net',
'nonce' => 'xITX1qgqlCDmYX6IrctN0WZRx7+Q4W7jjaXCCeUZnU8=',
'qop' => 'auth,auth-int',
'charset' => 'utf-8',
'algorithm' => 'md5-sess',
)
它并不完全漂亮,但它完成了工作。
答案 1 :(得分:0)
$decodedString = 'realm="smtp.domain.net",nonce="AJRUc5Jx0UQbv5SJ9FoyUnaZpqZIHDhLTU+Awn/K0Uw=",qop="auth,auth-int",charset=utf-8,algorithm=md5-sess';
parse_str(preg_replace('/(?:(")(.*?)("))?,(?:(")(.*?)("))?/','$1$2$3&$4$5$6',$decodedString), $values);
var_dump($values);
如果您想删除结果数组值周围的引号,请使用
$values = array_map(
function ($value) {
return trim($value,'"');
},
$values
);
var_dump($values);