使用 PHP 解包、处理和打包数组
use PHP to unpack, process and pack array
我从文件中读取字节并处理它们。之后我想保存打包的字节。
将混合 objects/types 的数组转换为字节字符串的推荐+通用方法是什么?在我的例子中:带有 int 和字符串的数组,包类型 a、C、x。
一个简化的例子:
// $bytes = fread($handle, 100);
$bytes = "437XYZ25.011001DBEFORE ....";
$unpackString = "a3CPN/x8spare/CDSC/x4spare/a32OPT";
$unpacked = unpack($unpackString, $bytes);
var_dump($unpacked);
/*
array(3) {
["CPN"]=> string(3) "437"
["DSC"]=> int(49)
["OPT"]=> string(32) "BEFORE "
}
*/
// example of processing
$unpacked["DSC"] = 12;
$unpacked["OPT"] = "AFTER ";
// pack + write the result
// $packString = "a3x8Cx4a32";
$packTypes = ["a3","x8","C","x4","a32"];
$packFields = [ $unpacked["CPN"], null, $unpacked["DSC"], null, $unpacked["OPT"] ];
// ...
update:在简化的示例中,我将 $packString
替换为 $packTypes
和 $packFields
以确保清楚内容属于什么在哪里以及用什么类型。
我想您正在寻找的是一种调用 pack
的方法,它接受带有关联数组的参数,就像您在示例中所使用的那样。为此,我们可以使用 call_user_func_array
,它通过名称调用函数并从给定数组中提供其参数。
$bytes = "437XYZ25.011001DBEFORE ....";
$unpackString = "a3CPN/x8spare/CDSC/x4spare/a32OPT";
$unpacked = unpack($unpackString, $bytes);
// example of processing
$unpacked["DSC"] = 12;
$unpacked["OPT"] = "AFTER ";
// pack + write the result
$packTypes = ["a3", "x8", "C", "x4", "a32"];
$packFields = [$unpacked["CPN"], null, $unpacked["DSC"], null, $unpacked["OPT"]];
$packString = "";
$packArguments = [];
for ($i = 0; $i < count($packTypes); $i++){
$packString .= $packTypes[$i];
if ($packFields[$i] !== null){
// the null bytes don't use an argument
$packArguments[] = $packFields[$i];
}
}
// put packString as the first argument
array_unshift($packArguments, $packString);
$output = call_user_func_array("pack", $packArguments);
然后 $output
将是:
00000000 34 33 37 00 00 00 00 00 00 00 00 0c 00 00 00 00 |437.............|
00000010 41 46 54 45 52 20 20 20 20 20 20 20 20 20 20 20 |AFTER |
00000020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
00000030
我从文件中读取字节并处理它们。之后我想保存打包的字节。
将混合 objects/types 的数组转换为字节字符串的推荐+通用方法是什么?在我的例子中:带有 int 和字符串的数组,包类型 a、C、x。
一个简化的例子:
// $bytes = fread($handle, 100);
$bytes = "437XYZ25.011001DBEFORE ....";
$unpackString = "a3CPN/x8spare/CDSC/x4spare/a32OPT";
$unpacked = unpack($unpackString, $bytes);
var_dump($unpacked);
/*
array(3) {
["CPN"]=> string(3) "437"
["DSC"]=> int(49)
["OPT"]=> string(32) "BEFORE "
}
*/
// example of processing
$unpacked["DSC"] = 12;
$unpacked["OPT"] = "AFTER ";
// pack + write the result
// $packString = "a3x8Cx4a32";
$packTypes = ["a3","x8","C","x4","a32"];
$packFields = [ $unpacked["CPN"], null, $unpacked["DSC"], null, $unpacked["OPT"] ];
// ...
update:在简化的示例中,我将 $packString
替换为 $packTypes
和 $packFields
以确保清楚内容属于什么在哪里以及用什么类型。
我想您正在寻找的是一种调用 pack
的方法,它接受带有关联数组的参数,就像您在示例中所使用的那样。为此,我们可以使用 call_user_func_array
,它通过名称调用函数并从给定数组中提供其参数。
$bytes = "437XYZ25.011001DBEFORE ....";
$unpackString = "a3CPN/x8spare/CDSC/x4spare/a32OPT";
$unpacked = unpack($unpackString, $bytes);
// example of processing
$unpacked["DSC"] = 12;
$unpacked["OPT"] = "AFTER ";
// pack + write the result
$packTypes = ["a3", "x8", "C", "x4", "a32"];
$packFields = [$unpacked["CPN"], null, $unpacked["DSC"], null, $unpacked["OPT"]];
$packString = "";
$packArguments = [];
for ($i = 0; $i < count($packTypes); $i++){
$packString .= $packTypes[$i];
if ($packFields[$i] !== null){
// the null bytes don't use an argument
$packArguments[] = $packFields[$i];
}
}
// put packString as the first argument
array_unshift($packArguments, $packString);
$output = call_user_func_array("pack", $packArguments);
然后 $output
将是:
00000000 34 33 37 00 00 00 00 00 00 00 00 0c 00 00 00 00 |437.............|
00000010 41 46 54 45 52 20 20 20 20 20 20 20 20 20 20 20 |AFTER |
00000020 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 | |
00000030