php pack()函數詳解與樣本

來源:互聯網
上載者:User
pack和unpack在一般的程式中還真的不容易見到,但是如果你用過很久以前的php產生excel你就會知道了。他的excel的頭就是pack出來的
最近在嘗試與C互動的時候又用上了這玩意,所以不得不再看看。其實就是C要求我一定要有包頭。。。其實純字串也不錯嘛。幹嘛非得搞個包頭呢?真糾結 .。
手冊上有pack與unpack的介紹,但都是英文的。。。

任何一款擁有socket操作能力的語言都有一個專門用於組包的函數,php也不例外!
用了很久php了卻很少有機會用php進行一些二進位操作。 最近用php寫一個socket用戶端串連一個用C++語言開發的遊戲服務端。 伺服器端開發人員使用了二進位的形式來定義協議的格式。協議格式如下:
包頭(2bytes)+加密(1byte)+命令碼(2bytes)+幀內容
1.包頭的內容是記錄幀內容的長度;
2. 加密:0表示不加密,1表示加密;
3. 命令碼為服務端命令識別符號;
一開始不瞭解php原來有pack可以來組裝二進位包, 走了彎路,讓服務端開發人員用C語言幫忙開發了的幾個記憶體操作函數,按照協議規則返回二進位包,然後我將這幾個方法編譯成一組擴充函數供php使用。

話歸正題,本文是介紹如何使用pack和unpack這兩個方法的。php官方手冊舉例太少,不能很容易理解,特別是那些格式化參數的使用。
轉摘的參數中文說明:
pack/unpack 的摸板字元字元 含義
a 一個填充空的位元組串
A 一個填充空格的位元組串
b 一個位串,在每個位元組裡位的順序都是升序
B 一個位串,在每個位元組裡位的順序都是降序
c 一個有符號 char(8位整數)值
C 一個無符號 char(8位整數)值;關於 Unicode 參閱 U
d 本機格式的雙精確度浮點數
f 本機格式的單精確度浮點數
h 一個十六進位串,低四位在前
H 一個十六進位串,高四位在前
i 一個有符號整數值,本機格式
I 一個不帶正負號的整數值,本機格式
l 一個有符號長整形,總是 32 位
L 一個無符號長整形,總是 32 位
n 一個 16位短整形,“網路”位元組序(大頭在前)
N 一個 32 位短整形,“網路”位元組序(大頭在前)
p 一個指向空結尾的字串的指標
P 一個指向定長字串的指標
q 一個有符號四倍(64位整數)值
Q 一個無符號四倍(64位整數)值
s 一個有符號短整數值,總是 16 位
S 一個無符號短整數值,總是 16 位,位元組序跟機器晶片有關
u 一個無編碼的字串
U 一個 Unicode 字元數字
v 一個“VAX”位元組序(小頭在前)的 16 位短整數
V 一個“VAX”位元組序(小頭在前)的 32 位短整數
w 一個 BER 壓縮的整數
x 一個空位元組(向前忽略一個位元組)
X 備份一個位元組
Z 一個空結束的(和空填充的)位元組串
@ 用空位元組填充絕對位置
string pack ( string $format [, mixed $args [, mixed $...]] )
一些規則:
1.每個字母后面都可以跟著一個數字,表示 count(計數),如果 count 是一個 * 表示剩下的所有東西。
2.如果你提供的參數比 $format 要求的少,pack 假設缺的都是空值。如果你提供的參數比 $format 要求的多,那麼多餘的參數被忽略。
下面還是用例子來說明用法會容易理解一點:

PHP代碼

  1. 關於Pack:
  2. 下面的第一部分把數字值封裝成位元組:
  3. $out = pack("CCCC", 65, 66, 67, 68); # $out 等於"ABCD"
  4. $out = pack("C4", 65, 66, 67, 68); # 一樣的東西
  5. 下面的對 Unicode 的迴圈字母做同樣的事情:
  6. $foo = pack("U4", 0x24b6, 0x24b7, 0x24b8, 0x24b9);
  7. 下面的做類似的事情,增加了一些空:
  8. $out = pack("CCxxCC", 65, 66, 67, 68); # $out 等於 "AB\0\0CD"
  9. 打包你的短整數並不意味著你就可移植了:
  10. $out = pack("s2", 1, 2);
  11. # 在小頭在前的機器上是 "\1\0\2\0"
  12. # 在大頭在前的機器上是 "\0\1\0\2"
  13. 在二進位和十六進位封裝上,count 指的是位或者半位元組的數量,而不是產生的位元組數量:
  14. $out = pack("B32", "...");
  15. $out = pack("H8", "5065726c"); # 都產生“Perl”
  16. a 域裡的長度只應用於一個字串:
  17. $out = pack("a4", "abcd", "x", "y", "z"); # "abcd"
  18. 要繞開這個限制,使用多倍聲明:
  19. $out = pack("aaaa", "abcd", "x", "y", "z"); # "axyz"
  20. $out = pack("a" x 4, "abcd", "x", "y", "z"); # "axyz"
  21. a 格式做空填充:
  22. $out = pack("a14", "abcdefg"); # " abcdefg\0\0\0\0\0\0"
  23. 關於unpack:
  24. array unpack ( string $format, string $data )
  25. $data = "010000020007";
  26. unpack("Sint1/Cchar1/Sint2/Cchar2",$data);
  27. ## array('int1'=>1, 'char1'=>'0','int2'=>2,'char2'=>7);
  28. 最後本文開頭講到的協議使用pack/unpack 舉常式序代碼為 :
  29. $lastact = pack('SCSa32a32',0x0040, 0x00, 0x0006, $username, $passwd );
  30. unpack('Sint1/Cchar1/Sint2/Cchar2/',$lastmessage);


學習資料:
http://blog.csdn.net/jojobb3138688/archive/2007/05/07/1598609.aspx
我上面的內容來自於:http://blog.sina.com.cn/s/blog_3eba8f1c0100nq9r.html,我現在已經順利的使用完了。黑黑
還有的參考資料:
http://bbs.phpchina.com/thread-104492-1-1.html
http://hi.baidu.com/chinetman/item/f78a71d847e7d638e2108fda

以上就介紹了php pack()函數詳解與樣本,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.