使用PHP解压缩,处理和打包数组

时间:2016-06-12 12:51:29

标签: php arrays pack

我从文件中读取字节并处理它们。之后我想保存打包的字节。

将具有混合对象/类型的数组转换为字节字符串的推荐+通用方法是什么?在我的例子中:带有int和string的数组,包类型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"] ];
// ...

更新:在简化示例中,我已将$packString替换为$packTypes$packFields,以确保清楚哪些内容属于何处以及使用何种类型。

1 个答案:

答案 0 :(得分:1)

我认为你正在寻找的是一种调用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