PHP 개발에서는 때로는 여러 데이터를 지정된 형식의 이진 문자열로 패키지 해야하는데, 이는 네트워크 전송 또는 파일 스토리지에 편리합니다. PHP가 제공하는 팩 함수는이 요구 사항을 달성 할 수 있지만 복잡한 형식 문자열로 전달해야하며 다양한 시나리오의 형식은 크게 다릅니다. 이 기사에서는 팩 기능을 사용하여 여러 형식을 지원하여 코드의 재사용 성과 유연성을 향상시키는 일반 포장 기능을 캡슐화하는 방법을 소개합니다.
팩 함수의 기본 구문은 다음과 같습니다.
string pack(string $format, mixed ...$values)
$ 형식 C 는 서명되지 않은 문자를 나타내는 형식을 지정하고 N은 16 비트 Big-Endian Endian Endian Integer 등을 나타냅니다.
$ 값은 해당 형식의 데이터입니다.
예를 들어, 서명되지 않은 2 개의 캐릭터와 16 비트 빅 엔디 언 정수를 포장하십시오.
$data = pack('CCn', 0x01, 0x02, 0x1234);
우리가 캡슐화하려는 기능 :
형식 문자열과 해당 값 배열을 허용합니다.
형식 문자열에 따라 값을 하나씩 자동으로 패키지합니다.
일반적인 형식 유형을 지원하며 확장에 편리합니다.
매개 변수 및 형식을 일치하지 않는 오류를 처리합니다.
예제 기능 서명 :
function universalPack(string $format, array $values): string
다음은 C , N , N , A 등을 지원하는 기본 구현입니다. 형식 :
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': // 16BIT BIG ENDIAN 바이트 순서
$result .= pack('n', $value);
break;
case 'N': // 32BIT BIG ENDIAN 바이트 순서
$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;
}
데이터 패킷을 패키지하려고한다고 가정하면 구조는 다음과 같습니다.
1 바이트 명령 번호 ( c )
2 바이트 데이터 길이 ( N )
4 바이트 데이터 ID ( N )
10 바이트 데이터 컨텐츠 (String, A10 )
Call example:
$command = 0x01;
$length = 14;
$dataId = 123456;
$content = "hello";
$packed = universalPack('CnNa10', [$command, $length, $dataId, $content]);
echo bin2hex($packed);
출력은 다음과 같습니다.
01000e0001e24068656c6c6f0000000000
팩 함수는 매우 강력하지만 형식과 값은 직접 사용할 때 오류가 발생하기 쉽습니다.
다중 형식 데이터의 패키징을 단순화하기 위해 범용 범용 팩 팩 함수를 캡슐화하십시오.
더 많은 형식 지원, 소규모 엔디 언 순서 지원 등과 같은 실제 요구에 따라 기능을 계속 향상시킬 수 있습니다.
실제 프로젝트에서 포장 풀기 기능은 포장 풀기 기능과 결합하여 피어 포장 기능을 달성 할 수 있습니다.