pack、unpack自制二进制“数据库”,packunpack
引言
pack、unpack函数,如果没有接触过socket,这个可能会比较陌生,这两个函数在socket交互的作用是组包,将数据装进一个二进制字符串,和对二进制字符串中的数据进行解包,这个里面有好多种格式,具体的格式可以去查查官方的手册(或者等看完本篇文章之后,去调用接口查看),我这里主要用了pack(“N”,int),pack(“a”,str)以及他们两个对应的解包函数,N在手册中的解释是下面这个,占4个字节,大端方式(其实就是低位在前还是在后的问题)。a是对字符串进行打包,不够指定的数值的时候用NULL(\0,或者说assic码0对应的字符)填充。
<p>N - unsigned long (always 32 bit, big endian byte order)</p>
<p>a - NUL-padded string</p>
我将用这个打包解包函数做一个函数手册查询小工具,或者可以说是一个自制小型二进制数据库。
设计数据格式
在做这个二进制文件数据库的时候我会创建两个文件,一个是索引文件,一个是要查询的数据的文件,分别看看他们的结构:
说明中括号内的数字为所占字节(bytes)数,"~"波浪线表示所占字节数不确定
数据文件,第一个php是一个正式的字符串"php",占4个字节,后面跟着版本说明,长度不确定(这个长度可以从后面的index文件中获取),接下来后面是存储信息的主体了。首先是一个函数名长度lenName占4个字节,接下来是函数名称,长度不确定,有前面的lenName对应的值确定,接下来是lenVal占4个字节,后面跟的是具体的函数说明内容,长度有前面的lenVal对应的值确定。
<pre class="code"><span> 内容存储格式定义 </span>++++++++++++++++++++++++++++++++++++++ |php(<span>4</span>) |版本说明(~) | ++++++++++++++++++++++++++++++++++++++ |lenName(<span>4</span>) |函数名称(~) | ++++++++++++++++++++++++++++++++++++++ |lenVal(<span>4</span>) |函数内容(~) | ++++++++++++++++++++++++++++++++++++++<span> ......</span>
索引文件,索引文件就比较简单了,其中全部存储了上面的存储文件中每个函数开始的指针位置,每个位置占用4个字节。
<pre class="code"><span>索引格式定义 </span>++++++++++++++++++++++++++++++++++++++ |position(<span>4</span>) | ++++++++++++++++++++++++++++++++++++++<span> ......</span>
查询的实现
由于存储文件中的内容是按照函数名顺序排序存储的,索引也是按照函数存储的顺序存储的,所以获取起来很方便,直接使用二分法就可以很轻松的获取到想要的函数
在查询的时候主要使用了下面几个方法:
第一、从制定位置获取一条索引的值(也就是对应的函数存储文件的指针位置)
<pre class="code"><span>/*</span><span>* * 从索引文件中获取一条记录的位置 * @param 索引文件中的开始位置,从开始位置获取四个字节为一个函数说明的开始位置 * @return 返回该索引位置所对应的存储位置指针偏移量 </span><span>*/</span> <span>private</span> <span>function</span> _getOneIndex(<span>$pos</span><span>) { </span><span>fseek</span>(<span>$this</span>->_indexHandle, <span>$pos</span><span>); </span><span>$len</span> = <span>unpack</span>("Nlen", <span>fread</span>(<span>$this</span>->_indexHandle, 4<span>)); </span><span>return</span> <span>$len</span>['len'<span>]; }</span>
第二、从指定的指针偏移位置获取一条len(4)+val(~)格式的内容
<pre class="code"><span>/*</span><span>* * 从制定的指针偏移量获取一个len+val型的内容 * @param $pos 文件的指针偏移量 * @return 返回数组,包括长度和值 </span><span>*/</span> <span>private</span> <span>function</span> _getStoreLenValFormat(<span>$pos</span><span>){ </span><span>fseek</span>(<span>$this</span>->_storeHandle, <span>$pos</span><span>); </span><span>$len</span> = <span>unpack</span>("Nlen", <span>fread</span>(<span>$this</span>->_storeHandle, 4<span>)); </span><span>$len</span> = <span>$len</span>['len'<span>]; </span><span>$val</span> = <span>fread</span>(<span>$this</span>->_storeHandle, <span>$len</span><span>); </span><span>return</span> <span>array</span><span> ( </span>'len' => <span>$len</span>, 'value' => <span>$val</span>,<span> ); }</span>
第三、获取制定函数的说明,这个也是最主要的一部分,使用二分法从数据文件中获取一条记录
<pre class="code"><span>/*</span><span>* * 获取函数内容 * @param 要查找的函数名称 * @return 返回函数说明的json字符串 </span><span>*/</span> <span>public</span> <span>function</span> get(<span>$func</span><span>) { </span><span>if</span>(!<span>$this</span>-><span>isInit()) </span><span>return</span><span>; </span><span>$begin</span> = 0<span>; </span><span>$end</span> = <span>filesize</span>(<span>$this</span>->_indexFile)/4<span>; </span><span>$ret</span> = '[]'<span>; </span><span>while</span>(<span>$begin</span> < <span>$end</span><span>){ </span><span>$mid</span> = <span>floor</span>((<span>$begin</span> + <span>$end</span>)/2<span>); </span><span>$pos</span> = <span>$mid</span>*4<span>; //$mid只是指针变量的位置,还需要乘上指针的长度4 </span><span>$pos</span> = <span>$this</span>->_getOneIndex(<span>$pos</span><span>); </span><span>$name</span> = <span>$this</span>->_getStoreLenValFormat(<span>$pos</span><span>); </span><span>$flag</span> = <span>strcmp</span>(<span>$func</span>, <span>$name</span>['value'<span>]); </span><span>if</span>(<span>$flag</span> == 0<span>){ </span><span>$val</span> = <span>$this</span>->_getStoreLenValFormat(<span>$pos</span>+4+<span>$name</span>['len'<span>]); </span><span>$ret</span> = <span>$val</span>['value'<span>]; </span><span>break</span><span>; }</span><span>elseif</span>(<span>$flag</span> < 0<span>){ </span><span>$end</span> = <span>$end</span> == <span>$mid</span> ? <span>$mid</span>-1 : <span>$mid</span><span>; }</span><span>else</span><span>{ </span><span>$begin</span> = <span>$begin</span> == <span>$mid</span> ? <span>$mid</span>+1 : <span>$mid</span><span>; } } </span><span>return</span> <span>$ret</span><span>; }</span>
使用很简单,只需包含类库文件和存储文件数据库,然后调用几句代码就可以
<pre class="code"><?<span>php </span><span>include_once</span>("./manual/phpManual.php"<span>); </span><span>$t</span> = <span>new</span><span> phpManual(); </span><span>$t</span>->init('zh'<span>); </span><span>echo</span> <span>$t</span>->get("unpack");
输出的是json字符串,转化后如下所示,其中有详细的说明,以及简洁的例子
<pre class="code"><span>{ </span>"name": "unpack"<span>, </span>"desc": "Unpack data from binary string."<span>, </span>"long_desc": "Unpacks from a binary string into an array according to the given `format`.\\n\\nThe unpacked data is stored in an associative array. To accomplish this you have to name the different format codes and separate them by a slash /. If a repeater argument is present, then each of the array keys will have a sequence number behind the given name."<span>, </span>"ver": "PHP 4, PHP 5"<span>, </span>"ret_desc": "Returns an associative array containing unpacked elements of binary string."<span>, </span>"seealso"<span>: [ </span>"pack"<span> ], </span>"url": "function.unpack"<span>, </span>"class": <span>null</span><span>, </span>"params"<span>: [ { </span>"list"<span>: [ { </span>"type": "string"<span>, </span>"var": "$format"<span>, </span>"beh": 0<span>, </span>"desc": "See pack() for an explanation of the format codes."<span> }, { </span>"type": "string"<span>, </span>"var": "$data"<span>, </span>"beh": 0<span>, </span>"desc": "The packed data."<span> } ], </span>"ret_type": "array"<span> } ], </span>"examples"<span>: [ { </span>"title": "unpack() example"<span>, </span>"source": "$binarydata = \"\\x04\\x00\\xa0\\x00\";\n$array = unpack(\"cchars/nint\", $binarydata);"<span>, </span>"output": <span>null</span><span> }, { </span>"title": "unpack() example with a repeater"<span>, </span>"source": "$binarydata = \"\\x04\\x00\\xa0\\x00\";\n$array = unpack(\"c2chars/nint\", $binarydata);"<span>, </span>"output": <span>null</span><span> }, { </span>"title": "unpack() example with unnamed keys"<span>, </span>"source": "$binarydata = \"\\x32\\x42\\x00\\xa0\";\n$array = unpack(\"c2/n\", $binarydata);\nvar_dump($array);"<span>, </span>"output": <span>null</span><span> } ] }</span>
最后再附上目录结构:
<pre class="code">+<span>phpManual </span>+<span>manual </span>+<span>phpManual </span>+<span>zh </span>|<span>_manualIndex </span>|<span>_manualStore </span>|<span>_phpManual.php </span>|_test.php
这个是程序的完整地址:
完整例子地址
参考
https://github.com/aizuyan/php-doc-parser 从这里拿到的phpmanual的全部数据
本文版权归作者iforever(luluyrt@163.com)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

PHP는 동적 웹 개발 및 서버 측 응용 프로그램에 사용되는 서버 측 스크립팅 언어입니다. 1.PHP는 편집이 필요하지 않으며 빠른 발전에 적합한 해석 된 언어입니다. 2. PHP 코드는 HTML에 포함되어 웹 페이지를 쉽게 개발할 수 있습니다. 3. PHP는 서버 측 로직을 처리하고 HTML 출력을 생성하며 사용자 상호 작용 및 데이터 처리를 지원합니다. 4. PHP는 데이터베이스와 상호 작용하고 프로세스 양식 제출 및 서버 측 작업을 실행할 수 있습니다.

PHP는 지난 수십 년 동안 네트워크를 형성했으며 웹 개발에서 계속 중요한 역할을 할 것입니다. 1) PHP는 1994 년에 시작되었으며 MySQL과의 원활한 통합으로 인해 개발자에게 최초의 선택이되었습니다. 2) 핵심 기능에는 동적 컨텐츠 생성 및 데이터베이스와의 통합이 포함되며 웹 사이트를 실시간으로 업데이트하고 맞춤형 방식으로 표시 할 수 있습니다. 3) PHP의 광범위한 응용 및 생태계는 장기적인 영향을 미쳤지 만 버전 업데이트 및 보안 문제에 직면 해 있습니다. 4) PHP7의 출시와 같은 최근 몇 년간의 성능 향상을 통해 현대 언어와 경쟁 할 수 있습니다. 5) 앞으로 PHP는 컨테이너화 및 마이크로 서비스와 같은 새로운 도전을 다루어야하지만 유연성과 활발한 커뮤니티로 인해 적응력이 있습니다.

PHP의 핵심 이점에는 학습 용이성, 강력한 웹 개발 지원, 풍부한 라이브러리 및 프레임 워크, 고성능 및 확장 성, 크로스 플랫폼 호환성 및 비용 효율성이 포함됩니다. 1) 배우고 사용하기 쉽고 초보자에게 적합합니다. 2) 웹 서버와 우수한 통합 및 여러 데이터베이스를 지원합니다. 3) Laravel과 같은 강력한 프레임 워크가 있습니다. 4) 최적화를 통해 고성능을 달성 할 수 있습니다. 5) 여러 운영 체제 지원; 6) 개발 비용을 줄이기위한 오픈 소스.

PHP는 죽지 않았습니다. 1) PHP 커뮤니티는 성능 및 보안 문제를 적극적으로 해결하고 PHP7.x는 성능을 향상시킵니다. 2) PHP는 최신 웹 개발에 적합하며 대규모 웹 사이트에서 널리 사용됩니다. 3) PHP는 배우기 쉽고 서버가 잘 수행되지만 유형 시스템은 정적 언어만큼 엄격하지 않습니다. 4) PHP는 컨텐츠 관리 및 전자 상거래 분야에서 여전히 중요하며 생태계는 계속 발전하고 있습니다. 5) Opcache 및 APC를 통해 성능을 최적화하고 OOP 및 설계 패턴을 사용하여 코드 품질을 향상시킵니다.

PHP와 Python에는 고유 한 장점과 단점이 있으며 선택은 프로젝트 요구 사항에 따라 다릅니다. 1) PHP는 웹 개발, 배우기 쉽고 풍부한 커뮤니티 리소스에 적합하지만 구문은 현대적이지 않으며 성능과 보안에주의를 기울여야합니다. 2) Python은 간결한 구문과 배우기 쉬운 데이터 과학 및 기계 학습에 적합하지만 실행 속도 및 메모리 관리에는 병목 현상이 있습니다.

PHP는 동적 웹 사이트를 구축하는 데 사용되며 해당 핵심 기능에는 다음이 포함됩니다. 1. 데이터베이스와 연결하여 동적 컨텐츠를 생성하고 웹 페이지를 실시간으로 생성합니다. 2. 사용자 상호 작용 및 양식 제출을 처리하고 입력을 확인하고 작업에 응답합니다. 3. 개인화 된 경험을 제공하기 위해 세션 및 사용자 인증을 관리합니다. 4. 성능을 최적화하고 모범 사례를 따라 웹 사이트 효율성 및 보안을 개선하십시오.

PHP는 MySQLI 및 PDO 확장 기능을 사용하여 데이터베이스 작업 및 서버 측 로직 프로세싱에서 상호 작용하고 세션 관리와 같은 기능을 통해 서버 측로 로직을 처리합니다. 1) MySQLI 또는 PDO를 사용하여 데이터베이스에 연결하고 SQL 쿼리를 실행하십시오. 2) 세션 관리 및 기타 기능을 통해 HTTP 요청 및 사용자 상태를 처리합니다. 3) 트랜잭션을 사용하여 데이터베이스 작업의 원자력을 보장하십시오. 4) SQL 주입 방지, 디버깅을 위해 예외 처리 및 폐쇄 연결을 사용하십시오. 5) 인덱싱 및 캐시를 통해 성능을 최적화하고, 읽을 수있는 코드를 작성하고, 오류 처리를 수행하십시오.

PHP에서 전처리 문과 PDO를 사용하면 SQL 주입 공격을 효과적으로 방지 할 수 있습니다. 1) PDO를 사용하여 데이터베이스에 연결하고 오류 모드를 설정하십시오. 2) 준비 방법을 통해 전처리 명세서를 작성하고 자리 표시자를 사용하여 데이터를 전달하고 방법을 실행하십시오. 3) 쿼리 결과를 처리하고 코드의 보안 및 성능을 보장합니다.


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

ZendStudio 13.5.1 맥
강력한 PHP 통합 개발 환경
