Current Location: Home> Latest Articles> Encapsulate a universal packaging function that supports multiple formats

Encapsulate a universal packaging function that supports multiple formats

M66 2025-05-29

In PHP development, sometimes we need to package multiple data into binary strings in the specified format, which is convenient for network transmission or file storage. The pack function provided by PHP can achieve this requirement, but it requires passing in complex format strings, and the formats of different scenarios vary greatly. This article will introduce how to use pack function to encapsulate a general packaging function that supports multiple formats to improve the reusability and flexibility of the code.


1. Introduction to pack function

The basic syntax of pack function is:

 string pack(string $format, mixed ...$values)
  • $format specifies the format, such as C represents unsigned characters, n represents 16-bit big-endian endian endian integer, etc.

  • $values ​​is data in the corresponding format.

For example, package two unsigned characters and a 16-bit big-endian integer:

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

2. Ideas for designing general packaging functions

The function we want to encapsulate:

  • Accepts a format string and corresponding array of values.

  • Automatically package values ​​one by one according to the format string.

  • Supports common format types and is convenient for expansion.

  • Handle errors that mismatch parameters and formats.

Example function signature:

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

Implement code examples

The following is a basic implementation that supports C , n , N , a, etc. formats:

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

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

        // Detect whether there are any duplicates,likea4、C2wait
        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("The number of values ​​does not match the format");
            }
            $value = $values[$valueIndex];
            $valueIndex++;

            switch ($char) {
                case 'C': // Unsigned characters
                    $result .= pack('C', $value);
                    break;
                case 'n': // 16Bit big endian byte order
                    $result .= pack('n', $value);
                    break;
                case 'N': // 32Bit big endian byte order
                    $result .= pack('N', $value);
                    break;
                case 'a': // NULFill string,Length byrepeatDecide
                    if ($repeat < 1) {
                        throw new InvalidArgumentException("aThe format needs to be specified in length");
                    }
                    $str = str_pad(substr($value, 0, $repeat), $repeat, "\0");
                    $result .= $str;
                    // aFormat processing all at oncerepeat,valueIndexNo increment
                    $valueIndex--;
                    break;
                default:
                    throw new InvalidArgumentException("Unsupported format characters: $char");
            }
        }
    }

    return $result;
}

IV. Use examples

Suppose you want to package a data packet, the structure is:

  • 1 byte command number ( C )

  • 2 byte data length ( n )

  • 4 byte data ID ( N )

  • 10 byte data content (string, a10 )

Call example:

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

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

The output is:

 01000e0001e24068656c6c6f0000000000

5. Summary

  • Pack functions are very powerful, but the format and value are prone to errors when used directly.

  • Encapsulate a universal universalPack function to simplify the packaging of multi-format data.

  • Functions can continue to be enhanced according to actual needs, such as supporting more formats, supporting small-endian order, etc.

  • In actual projects, the unpack function can also be combined with the unpack function to achieve peer unpacking function.