現在の位置: ホーム> 最新記事一覧> 複数の形式をサポートするユニバーサルパッケージ関数をカプセル化します

複数の形式をサポートするユニバーサルパッケージ関数をカプセル化します

M66 2025-05-29

PHP開発では、ネットワーク伝送またはファイルストレージに便利な、指定された形式のバイナリ文字列に複数のデータをパッケージ化する必要がある場合があります。 PHPが提供するパック関数はこの要件を達成できますが、複雑な形式の文字列を渡す必要があり、さまざまなシナリオの形式は大きく異なります。この記事では、パック関数を使用して、複数の形式をサポートしてコードの再利用性と柔軟性を向上させる一般的なパッケージング機能をカプセル化する方法を紹介します。


1。パック関数の概要

パック関数の基本的な構文は次のとおりです。

 string pack(string $format, mixed ...$values)
  • $フォーマットはcなどの形式を指定します。Cは署名されていない文字を表し、 nは16ビットのビッグエンディアンエンディアン整数などを表します。

  • $値は、対応する形式のデータです。

たとえば、2つの署名されていないキャラクターと16ビットのビッグエンディアン整数をパッケージ化します。

 $data = pack('CCn', 0x01, 0x02, 0x1234);

2。一般的なパッケージング機能を設計するためのアイデア

カプセル化する機能:

  • フォーマット文字列と対応する値の配列を受け入れます。

  • フォーマット文字列に従って、自動的にパッケージを1つずつパッケージします。

  • 一般的な形式タイプをサポートし、拡張に便利です。

  • パラメーターの不一致と形式のエラーを処理します。

機能の署名:

 function universalPack(string $format, array $values): string

コードの例を実装します

以下は、 CNNAなどをサポートする基本的な実装です。形式:

 function universalPack(string $format, array $values): string {
    $result = '';
    $formatLength = strlen($format);
    $valueIndex = 0;

    for ($i = 0; $i < $formatLength; $i++) {
        $char = $format[$i];
        $repeat = 1;

        // 重複があるかどうかを検出します,のようにa4、C2待って
        if (isset($format[$i + 1]) && ctype_digit($format[$i + 1])) {
            $repeat = (int)$format[$i + 1];
            $i++;
        }

        for ($r = 0; $r < $repeat; $r++) {
            if (!isset($values[$valueIndex])) {
                throw new InvalidArgumentException("値の数は形式と一致しません");
            }
            $value = $values[$valueIndex];
            $valueIndex++;

            switch ($char) {
                case 'C': // 署名されていない文字
                    $result .= pack('C', $value);
                    break;
                case 'n': // 16ビットビッグエンディアンバイトオーダー
                    $result .= pack('n', $value);
                    break;
                case 'N': // 32ビットビッグエンディアンバイトオーダー
                    $result .= pack('N', $value);
                    break;
                case 'a': // NUL文字列を入力します,長さrepeat決める
                    if ($repeat < 1) {
                        throw new InvalidArgumentException("a形式は長さで指定する必要があります");
                    }
                    $str = str_pad(substr($value, 0, $repeat), $repeat, "\0");
                    $result .= $str;
                    // aすべての処理を一度にフォーマットしますrepeat,valueIndex増分なし
                    $valueIndex--;
                    break;
                default:
                    throw new InvalidArgumentException("サポートされていないフォーマット文字: $char");
            }
        }
    }

    return $result;
}

IV。例を使用してください

データパケットをパッケージ化するとしますが、構造は次のとおりです。

  • 1バイトコマンド番号( c

  • 2バイトデータ長( n

  • 4バイトデータID( n

  • 10バイトデータコンテンツ(String、 A10

コール例:

 $command = 0x01;
$length = 14;
$dataId = 123456;
$content = "hello";

$packed = universalPack('CnNa10', [$command, $length, $dataId, $content]);
echo bin2hex($packed);

出力は次のとおりです。

 01000e0001e24068656c6c6f0000000000

5。概要

  • パック関数は非常に強力ですが、形式と値は直接使用するとエラーが発生しやすくなります。

  • ユニバーサルユニバーサルパック関数をカプセル化して、マルチフォーマットデータのパッケージを簡素化します。

  • 機能は、より多くのフォーマットをサポートしたり、小規模な秩序をサポートするなど、実際のニーズに応じて強化され続けることができます。

  • 実際のプロジェクトでは、開梱関数を開梱機能と組み合わせて、ピア開梱機能を実現することもできます。