我一直试图弄清楚 Pack/Unpack 的 PHP 实现是否可以做 Perl 版本能够做的事情。我希望能够用 PHP 实现的示例是:
http://perldoc.perl.org/perlpacktut.html#String-Lengths
# pack a message: ASCIIZ, ASCIIZ, length/string, byte
my $msg = pack( 'Z* Z* C/A* C', $src, $dst, $sm, $prio );
# unpack
( $src, $dst, $sm, $prio ) = unpack( 'Z* Z* C/A* C', $msg );
该 Perl 代码的作用描述如下:
用斜杠 (/) 将两个包代码组合在一起,将它们与
参数列表中的单个值。在包装中,长度
根据第一个代码获取并打包参数,而
参数本身是用模板代码转换后添加的
斜线之后。
即,您可以打包可变长度字符串,然后一步解包它们,而不必首先计算出字符串的长度,然后将其作为单独的步骤提取。
PHP 手册没有提到这种功能,任何将“C/A*”这样的模式插入到 unpack 中的尝试都会给我带来错误。这是手册中的疏忽还是 PHP 版本不支持的内容?
遗憾的是,PHP 的打包和解包函数不提供像 Perl 那样的变量(空终止)字符串的自动打包和解包功能。
为了适应此功能,请考虑将 unpack 函数包装到辅助类中,如下所示:
class Packer {
static function unpack($mask, $data, &$pos) {
try {
$result = array();
$pos = 0;
foreach($mask as $field) {
$subject = substr($data, $pos);
$type = $field[0];
$name = $field[1];
switch($type) {
case 'N':
case 'n':
case 'C':
case 'c':
$temp = unpack("{$type}temp", $subject);
$result[$name] = $temp['temp'];
if($type=='N') {
$result[$name] = (int)$result[$name];
}
$pos += ($type=='N' ? 4 : ($type=='n' ? 2 : 1));
break;
case 'a':
$nullPos = strpos($subject, "\0") + 1;
$temp = unpack("a{$nullPos}temp", $subject);
$result[$name] = $temp['temp'];
$pos += $nullPos;
break;
}
}
return $result;
} catch(Exception $e) {
$message = $e->getMessage();
throw new Exception("unpack failed with error '{$message}'");
}
}
}
请注意,该函数并未实现所有解包类型,仅作为示例。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)