2016-06-12 1 views
1

Je lis les octets d'un fichier et les traite. Ensuite, je voudrais enregistrer les octets emballés.utiliser PHP pour décompresser, traiter et emballer le tableau

Quelle est la méthode générique recommandée pour convertir un tableau avec des objets/types mixtes en une chaîne d'octets? Dans mon cas: array avec int et string, pack types a, C, x.

Un exemple simplifié:

// $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"] ]; 
// ... 

mise à jour: dans l'exemple simplifié j'ai remplacé $packString avec $packTypes et $packFields pour vous assurer qu'il est clair que le contenu appartient où et avec quel type.

+0

Quelle est la question? Vous utilisez 'unpack' pour décompresser le tableau, pourquoi ne pouvez-vous pas utiliser' pack' pour l'emballer à nouveau? Le problème est-il dû au fait que 'pack' accepte des arguments au lieu d'un seul tableau? –

+0

En effet. Comment emballer en utilisant le tableau. – wivku

Répondre

1

Je suppose que ce que vous cherchez est un moyen d'appeler pack, qui accepte les arguments avec un tableau associatif comme vous avez dans votre exemple. Pour cela, nous pouvons utiliser call_user_func_array qui appelle une fonction par son nom et fournit ses arguments depuis un tableau donné.

$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); 

Et $output serait alors:

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 
+1

Merveilleux. J'ai vu l'approche call_user_func_array avant mais il manquait le contexte. Merci! – wivku