이 글은 PHP의 pack 기능과 unpack 기능(코드 포함)에 대해 자세히 소개합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
PHP에는 pack
및 unpack
이라는 두 가지 중요한 인기 없는 기능이 있습니다. 네트워크 프로그래밍, 이미지 파일 읽기 및 쓰기와 같은 시나리오에서는 이 두 기능이 거의 필수적입니다. 파일 읽기 및 쓰기/네트워크 프로그래밍 또는 바이트 스트림 처리의 중요성을 고려하면 이 두 기능을 마스터하는 것이 고급 PHP 프로그래밍의 기초입니다. pack
和unpack
。在网络编程,读写图像文件等场景,这两个函数几乎必不可少。鉴于文件读写/网络编程,或者说字节流处理的重要性,掌握这两个函数是迈向高级PHP编程的基础。
本文先介绍字节
和字符
的区别,说明两个函数存在的必要性和重要性。然后介绍基本用法和使用场景,让读者对其有大体了解,为实际使用中奠定基础。
字节和字符
PHP的优势是简单易用,熟练运用 字符串 和 数组 相关函数就能抗住一般的需求。日常工作中多用到字符串,所以PHP开发对字符都比较熟悉,稍微资深点基本能也能弄清字符编码。但字符的伴生概念:字节,不少PHP开发并不知晓/熟悉。
这不怪他们。PHP世界里极少出现“字节(流)”的概念:没有byte关键字(当然也没有char),官方文档也没提字节;没有原生的数组支持(常用的array其实是hashtable);当然字符串(string)能表达其他语言中的字节数组(Byte Array, byte[])。
字节和字符有什么联系和区别呢?简单来说字节是计算机存储和操作的最小单位,字符是人们阅读的最小单位;字节是存储(物理)概念,字符是逻辑概念;字节代表数据(内涵和本质),字符代表其含义;字符由字节组成。
举几个例子说明两者区别:“中国”包含2个字符,GBK编码表示需要4个字节,UTF-8编码需要6个字节;数字“1234567890”,包含10个字符,用int32类型表示只需4个字节;下面的图片占用42582个字节,用字符表示是“我老婆”,只占用3个字符:
再举一个常用的例子说明字符和字节的区别。开发中我们常用md5算法获取数据的哈希值,算法返回一个128位(bit)的数据(16个字节)。为方便查看其值,人们约定成俗地用十六进制表示,结果就是我们熟知的32位长度的字符串(不区分大小写)。32长度字符串不是md5算法的必然结果,16字节数据才是其本质。如果你愿意,可以用一个小于2^128的数字表示哈希结果,也可以将16字节base64编码后作为其结果。所以常用的32位哈希值与md5返回的16字节关系为:一个是字符表示,另一个则是其本质(字符数组)(PHP的md5函数第二个参数值为true便可得到16字节数据,或hash函数第三个参数为true)。
相关概念还有字节序、字符编码等,本文不做展开。
引言
PHP中专门处理字符串的函数有几十个,加上正则、时间等函数,字符串处理的函数不下百个。相比之下字节处理门庭冷落,相关函数寥寥无几。除了常用的ord/chr
,哈希加密函数返回的原始字节、openssl库的openssl_random_pseudo_bytes
等函数真正处理或返回 字节外,最重要的两个字节处理函数是pack
和unpack
。
本节从问题引出pack
函数的使用。
问题
考虑一个简单的问题:宇宙的终极答案42在内存中是如何表示的(或者说怎么获取其字节数组)?
因为42是一个整数,根据硬件不同,其占用字节大小可能为1, 2, 4, 8等。这里我们限定一个整数占用4个字节,于是问题的等价表述为:怎样将一个整数转换成字节数组(本机序,4个字节)?
分析
因为是多字节,所以要考虑字节序的问题。42不超过255,只占用一个字节,故而其他三个字节都是0。据此得到结论:如果是大端序(低位字节存放在地址高位),四个字节分别是:0 0 0 42;如果是小端序,结果则是:42 0 0 0。
那怎么知道机器的字节序呢?PHP没有提供相关功能,也不能像C
语言直接取地址访问字节数据。无所不能的PHP该怎么搞定字节序,或者说完成数据向字节的转换?
方案
PHP应用层面,数据向字节(数组)的转换是pack
的专场,字节(数组)向数据的转换则是unpack
바이트
와 문자
의 차이점을 소개하고, 두 기능의 존재 필요성과 중요성을 설명합니다. 그런 다음 기본적인 사용 및 사용 시나리오를 소개하여 독자에게 일반적인 이해를 제공하고 실제 사용을 위한 기반을 마련합니다. 🎜바이트 및 문자🎜🎜PHP의 장점은 간단하고 사용하기 쉽다는 것입니다. 문자열 및 배열 관련 기능을 능숙하게 사용할 수 있습니다. 일반적인 필요. 문자열은 일상 업무에서 자주 사용되기 때문에 PHP 개발자는 문자에 익숙하고, 경험이 적은 사람도 기본적으로 문자 인코딩을 파악할 수 있습니다. 그러나 많은 PHP 개발자는 문자에 수반되는 개념인 바이트를 인식하지 못하거나 익숙하지 않습니다. 🎜🎜그들의 잘못이 아닙니다. "바이트(스트림)" 개념은 PHP 세계에서는 거의 나타나지 않습니다. byte 키워드도 없고(물론 char도 없습니다) 공식 문서에는 기본 배열 지원이 없다고 언급되어 있습니다(일반적으로 사용되는 배열은 다음과 같습니다). 실제로는 해시테이블); 물론 문자열은 다른 언어로 바이트 배열(Byte Array, byte[])을 표현할 수 있습니다. 🎜🎜바이트와 문자의 연결과 차이점은 무엇인가요? 간단히 말해, 바이트는 컴퓨터 저장 및 작동의 최소 단위이고 문자는 사람이 읽을 수 있는 최소 단위입니다. 바이트는 저장(물리적) 개념이고 문자는 데이터(의미 및 본질)를 나타내는 논리적 개념입니다. ;문자는 바이트로 구성됩니다. 🎜🎜둘 사이의 차이점을 설명하기 위해 몇 가지 예를 들어보세요. "중국"에는 2개의 문자가 포함되고, GBK 인코딩에는 4바이트가 필요하며, UTF-8 인코딩에는 6바이트가 필요하며, 숫자 "1234567890"에는 int32를 사용하여 10개의 문자가 포함됩니다. 4바이트만 필요합니다. 아래 그림은 42582바이트를 차지하고 문자 표현은 "my wife"로 3자만 차지합니다. 🎜🎜🎜🎜문자와 바이트 간의 차이를 설명하는 또 다른 일반적인 예입니다. 개발 중에는 md5 알고리즘을 사용하여 데이터의 해시 값을 얻는 경우가 많습니다. 이 알고리즘은 128비트 데이터(16바이트)를 반환합니다. 해당 값을 쉽게 보기 위해 사람들은 일반적으로 16진수 표현을 사용하며 그 결과는 잘 알려진 32비트 문자열(대소문자를 구분하지 않음)입니다. 32바이트 길이의 문자열은 md5 알고리즘의 불가피한 결과가 아니며, 16바이트 데이터가 그 본질입니다. 원하는 경우 2^128보다 작은 숫자를 사용하여 해시 결과를 표시하거나 결과로 16바이트를 base64로 인코딩할 수 있습니다. 따라서 일반적으로 사용되는 32비트 해시 값과 md5가 반환하는 16바이트 사이의 관계는 다음과 같습니다. 하나는 문자 표현이고 다른 하나는 본질(문자 배열)입니다(PHP md5 함수의 두 번째 매개 변수 값은 true입니다). 16자 섹션 데이터를 가져오거나 해시 함수의 세 번째 매개변수가 true입니다.) 🎜🎜관련 개념에는 바이트 순서, 문자 인코딩 등이 포함되며, 이 기사에서는 이에 대해 확장하지 않습니다. 🎜
소개🎜🎜PHP에는 문자열 처리를 전문으로 하는 수십 가지 함수와 일반 함수, 시간 함수, 기타 함수, 문자열 처리가 있습니다. 기능은 백 개 이상입니다. 이에 비해 바이트 처리는 대중적이지 않고 관련 기능도 소수에 불과하다. 일반적으로 사용되는 现在我们用 调用函数便返回本机是否大端序。 上述是pack函数简单的使用场景,接下来分别介绍pack和unpack函数。 pack和unpack pack函数 pack是“打包/封包”的意思。如其名,pack函数的工作是将数据按照格式打包成字节数组。函数原型为: 形式上与 上文的例子中使用了"l"和"s"两个格式化元字符, 字符串: 字节: char/short/int/long/float/double六种基本类型: 注意:char和a/A等的区别是a/A等输入为字符(串),而's/S'的输入要求是小于256的整数,输入字符会得到0。 量词比较简单:数字和""两种。例如"i2"表示将两个参数按照整数转换,"c"表示后续都按照char类型转换。 unpack unpack是pack的反向操作:将字节数组解析成有意义的数据。其函数原型为: unpack函数需要注意的是第一个参数和返回值。返回值好理解,pack函数相当于将除格式化参数外的参数数组(想象成call_user_func_array的参数)变成一个字节数组;unpack做相反的事情:释放数据,得到输入时的参数数组。 返回一个数组,其键分别是什么呢?这便是格式化参数($format)在pack和unpack的不同之处:unpack应该对释放出来的数据命名,用"/"分隔各组数据。由于格式化参数允许有非元字符和量词外的字符,为了区分数据,不同数据间的"/"分隔符必不可少。 一个例子: 如果不对释放出来的数据命名会怎么样?例如上例中 为何?官方文档上如是说: 翻译过来就是:如果你不对数据命名,默认的1, 2, 3...就用来当作键值。如果有多组数据,每组都用同样的下标,会导致数据覆盖。 所以能理解 "i/a/a*" 为何只剩最后一组数据了吧? 读取图像、word/excel文件,解析binlog、二进制ip数据库文件等场合, 假设我们的tcp包格式为:前四个字节表示包大小,其余字节为数据内容。于是客户(发送)端的 服务(接收)端根据协议解析接收到的数据流: 通过pack和unpack,我们顺利的处理报文协议和二进制字节流的发送和解析。 如果你用\n作为报文分隔符,pack和unpack也许用不到。但在网络通讯中直接传递字符毕竟少数(相当于明文传送),大多数情况下的二进制数据流的解析还是要靠pack和unpack。 总结 메모리 할당 외에도 가장 중요한 시스템 호출은 파일 읽기 및 쓰기와 네트워크 연결이며, 둘 다의 필수 작업 개체는 바이트 스트림입니다. ord/chr
외에도 해시 암호화 함수에서 반환된 원본 바이트, openssl 라이브러리의 openssl_random_pseudo_bytes
및 기타 함수가 실제로 처리하거나 반환합니다. Strong> 바이트 또한 가장 중요한 두 가지 바이트 처리 기능은 pack
및 unpack
입니다. 🎜🎜이 부분은 문제에서 pack
함수를 사용하는 방법으로 이어집니다. 🎜질문
🎜간단한 질문을 생각해 보세요. 우주42에 대한 궁극적인 대답은 메모리에 어떻게 표현됩니까(또는 바이트 배열을 얻는 방법)? 🎜🎜42는 정수이므로 하드웨어에 따라 차지하는 바이트 크기는 1, 2, 4, 8 등이 될 수 있습니다. 여기서는 정수가 4바이트를 차지하도록 제한하므로 문제에 대한 동등한 공식은 다음과 같습니다. 정수를 바이트 배열(기본 순서, 4바이트)로 변환하는 방법은 무엇입니까? 🎜분석
🎜멀티바이트이기 때문에 바이트 순서 문제를 고려해야 합니다. 42는 255를 넘지 않고 1바이트만 차지하므로 나머지 3바이트는 모두 0이다. 이를 바탕으로 결론을 내릴 수 있습니다. 빅엔디안(하위 바이트가 상위 주소에 저장됨)인 경우 4바이트는 다음과 같습니다. 0 0 0 42; 리틀 엔디안이므로 결과는 42 0 0 0입니다. 🎜🎜그럼 머신의 바이트 순서는 어떻게 알 수 있나요? PHP는 관련 기능을 제공하지 않으며, C
언어와 같은 주소에 접근하여 바이트 데이터에 직접 접근할 수도 없습니다. 강력한 PHP는 어떻게 바이트 순서를 수정하거나 데이터를 바이트로 변환하는 작업을 완료할 수 있나요? 🎜Scheme
🎜PHP 애플리케이션 레벨에서 데이터를 바이트(배열)로 변환하는 것은 pack
의 특수 이벤트이며, 바이트(배열)를 데이터로 변환하는 것은 unpack
의 특별한 퍼포먼스를 만나보세요. 이 두 함수 외에는 바이트 배열(또는 바이너리 데이터)을 데이터로 변환하는 것이 거의 불가능합니다. (가능하다면 조언 부탁드립니다.) 🎜pack
函数获取42在内存中的字节数组。相关代码如下:function intToBytes(int $num) : string {
return pack("l", $num);
}
function outputBytes(string $bytes) {
echo "bytes: ";
for ($i = 0; $i <p>本人计算机用的英特尔的CPU,x86架构是小端序,所以程序输出符合预期。</p><p>延伸一下,怎么判断机器的字节序?有了<code>pack</code>函数,答案非常简单:</p><pre class="brush:php;toolbar:false">function bigEndian() : bool {
$data = 0x1200;
$bytes = pack("s", $data);
return ord($bytes[0]) === 0x12;
}
printf
系列函数相同:第一个参数是格式字符串,其余参数是要格式化的参数。不同之处在于pack
函数的格式中不能出现元字符和量词外的其他字符,所以不需要%
符号。pack
函数的元字符主要分为三类:
a
、A
等;将数据转成字符串,功能上与sprintf
类似,例如整数32转换成字符串"32";h
和H
;对字节进行16进制编码,区别在于低位还是高位在前,功能上与dechex
等函数类似;c/s/i/l
等;将数据转换成对应类型的字节数组,除char
类型外(暂)没有其他函数可替代;unpack ( string $format , string $data [, int $offset = 0 ] ) : array
$bytes = pack("iaa*", 42, ":", "The answer to life, the universe and everything");
outputBytes($bytes);
$result = unpack("inumber/acolon/a*word", $bytes);
print_r($result);
// 程序输出:
bytes: 42 0 0 0 58 84 104 101 32 97 110 115 119 101 114 32 116 111 32 108 105 102 101 44 32 116 104 101 32 117 110 105 118 101 114 115 101 32 97 110 100 32 101 118 101 114 121 116 104 105 110 103
Array
(
[num] => 42
[colon] => :
[word] => The answer to life, the universe and everything
)
unpack
的格式化参数为:"i/a/a*",结果是什么呢?其结果为:Array
(
[1] => The answer to life, the universe and everything
)
Caution If you do not name an element, numeric indices starting from 1 are used. Be aware that if you have more than one unnamed element, some data is overwritten because the numbering restarts from 1 for each element.
应用场景
pack
和unpack
几乎必不可少。本文举例说一下pack
和unpack
在网络编程时协议解析的用途。send
函数可以长这样:public function send($data) {
// 这里假设$data已经做了序列化、加密等操作,是字节数组
// 计算报文长度,封装报文
$len = strlen($data);
$header = pack("L", $len);
// 转换成网络(大端)序
$header = xxx
// 封包
$binary = $header . $data;
// 调用fwrite/socket_send等将数据写入内核缓冲区
...
}
public function decodable($session, $buffer) {
$dataLen = strlen($buffer);
// 非法数据包
if ($dataLen 8 * 1024 * 1024) {
// 关闭连接等
return NOT_OK;
}
// 检查数据包是否满足协议要求
if ($dataLen - 4 >= $len) {
return OK;
}
// 数据未全部到达,继续等待
return NEED_DATA;
}
pack
和unpack
이진 데이터 처리에 매우 유용한 하위 수준 바이트 작업을 수행할 수 있는 기능을 PHP에 제공합니다. 웹 프로그래밍에서 벗어나고 싶은 PHP 개발자는 이 두 가지 기능을 마스터해야 합니다.
위 내용은 PHP의 pack 기능과 unpack 기능에 대한 자세한 소개(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

PHP는 전자 상거래, 컨텐츠 관리 시스템 및 API 개발에 널리 사용됩니다. 1) 전자 상거래 : 쇼핑 카트 기능 및 지불 처리에 사용됩니다. 2) 컨텐츠 관리 시스템 : 동적 컨텐츠 생성 및 사용자 관리에 사용됩니다. 3) API 개발 : 편안한 API 개발 및 API 보안에 사용됩니다. 성능 최적화 및 모범 사례를 통해 PHP 애플리케이션의 효율성과 유지 보수 성이 향상됩니다.

PHP를 사용하면 대화식 웹 컨텐츠를 쉽게 만들 수 있습니다. 1) HTML을 포함하여 컨텐츠를 동적으로 생성하고 사용자 입력 또는 데이터베이스 데이터를 기반으로 실시간으로 표시합니다. 2) 프로세스 양식 제출 및 동적 출력을 생성하여 htmlspecialchars를 사용하여 XSS를 방지합니다. 3) MySQL을 사용하여 사용자 등록 시스템을 작성하고 Password_Hash 및 전처리 명세서를 사용하여 보안을 향상시킵니다. 이러한 기술을 마스터하면 웹 개발의 효율성이 향상됩니다.

PHP와 Python은 각각 고유 한 장점이 있으며 프로젝트 요구 사항에 따라 선택합니다. 1.PHP는 웹 개발, 특히 웹 사이트의 빠른 개발 및 유지 보수에 적합합니다. 2. Python은 간결한 구문을 가진 데이터 과학, 기계 학습 및 인공 지능에 적합하며 초보자에게 적합합니다.

PHP는 여전히 역동적이며 현대 프로그래밍 분야에서 여전히 중요한 위치를 차지하고 있습니다. 1) PHP의 단순성과 강력한 커뮤니티 지원으로 인해 웹 개발에 널리 사용됩니다. 2) 유연성과 안정성은 웹 양식, 데이터베이스 작업 및 파일 처리를 처리하는 데 탁월합니다. 3) PHP는 지속적으로 발전하고 최적화하며 초보자 및 숙련 된 개발자에게 적합합니다.

PHP는 현대 웹 개발, 특히 컨텐츠 관리 및 전자 상거래 플랫폼에서 중요합니다. 1) PHP는 Laravel 및 Symfony와 같은 풍부한 생태계와 강력한 프레임 워크 지원을 가지고 있습니다. 2) Opcache 및 Nginx를 통해 성능 최적화를 달성 할 수 있습니다. 3) PHP8.0은 성능을 향상시키기 위해 JIT 컴파일러를 소개합니다. 4) 클라우드 네이티브 애플리케이션은 Docker 및 Kubernetes를 통해 배포되어 유연성과 확장 성을 향상시킵니다.

PHP는 특히 빠른 개발 및 동적 컨텐츠를 처리하는 데 웹 개발에 적합하지만 데이터 과학 및 엔터프라이즈 수준의 애플리케이션에는 적합하지 않습니다. Python과 비교할 때 PHP는 웹 개발에 더 많은 장점이 있지만 데이터 과학 분야에서는 Python만큼 좋지 않습니다. Java와 비교할 때 PHP는 엔터프라이즈 레벨 애플리케이션에서 더 나빠지지만 웹 개발에서는 더 유연합니다. JavaScript와 비교할 때 PHP는 백엔드 개발에서 더 간결하지만 프론트 엔드 개발에서는 JavaScript만큼 좋지 않습니다.

PHP와 Python은 각각 고유 한 장점이 있으며 다양한 시나리오에 적합합니다. 1.PHP는 웹 개발에 적합하며 내장 웹 서버 및 풍부한 기능 라이브러리를 제공합니다. 2. Python은 간결한 구문과 강력한 표준 라이브러리가있는 데이터 과학 및 기계 학습에 적합합니다. 선택할 때 프로젝트 요구 사항에 따라 결정해야합니다.

PHP는 서버 측에서 널리 사용되는 스크립팅 언어이며 특히 웹 개발에 적합합니다. 1.PHP는 HTML을 포함하고 HTTP 요청 및 응답을 처리 할 수 있으며 다양한 데이터베이스를 지원할 수 있습니다. 2.PHP는 강력한 커뮤니티 지원 및 오픈 소스 리소스를 통해 동적 웹 컨텐츠, 프로세스 양식 데이터, 액세스 데이터베이스 등을 생성하는 데 사용됩니다. 3. PHP는 해석 된 언어이며, 실행 프로세스에는 어휘 분석, 문법 분석, 편집 및 실행이 포함됩니다. 4. PHP는 사용자 등록 시스템과 같은 고급 응용 프로그램을 위해 MySQL과 결합 할 수 있습니다. 5. PHP를 디버깅 할 때 error_reporting () 및 var_dump ()와 같은 함수를 사용할 수 있습니다. 6. 캐싱 메커니즘을 사용하여 PHP 코드를 최적화하고 데이터베이스 쿼리를 최적화하며 내장 기능을 사용하십시오. 7


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

PhpStorm 맥 버전
최신(2018.2.1) 전문 PHP 통합 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기
