ÍøÂçͨÐÅ¡¢Îļþ´ae´¢Öо³£ÐeÒª½»»»Êý¾Ý£¬ÎªÁ˼oÉÙÍøÂçͨÐÅÁ÷Á¿¡¢Îļþ´ae´¢´oСÒÔ¼°¼ÓÃÜͨÐŹaeÔo£¬¾³£ÐeÒª¶ÔÊý¾Ý½øÐÐË«Ïo¼Ó½aÃÜÒÔ±£Ö¤Êý¾ÝµÄ°²È«¡£
PHPÖÐʵÏִ˹¦ÄÜÖ÷ÒªÐeҪʹÓõĺ¯ÊýÖ÷ÒªÊÇpack¼°unpackº¯Êý
pack
ѹËo×ÊÁϵ½Î»×Ö*u´®Ö®ÖС£
Ói*¨: string pack(string format, mixed [args]...);
µ»ØÖµ: ×Öu´®
±¾º¯ÊýÓÃÀ´½«×ÊÁÏѹËo´o°uµ½Î»µÄ×Ö*u´®Ö®ÖС£
a - NUL- ×Öu´®ÌiÂu[padded string] ½«×Öu´®¿Õ°×ÒÔ NULL ×Ö*uÌiÂu
A - SPACE- ×Ö*u´®ÌiÂu[padded string]
h ¨C Ê®Áu½øÖÆ×Ö*u´®£¬µÍ¡°ËÄλԪ¡±[low nibble first] (µÍλÔÚÇ°)
H - Ê®Áu½øÖÆ×Ö*u´®£¬¸ß¡°ËÄλԪ¡±high nibble first
c ¨C ´øÓÐuºÅµÄ×Öu
C ¨C ²»´øÓÐuºÅµÄ×Öu
s ¨C ´øÓÐ*uºÅµÄ¶Ìģʽ[short]£¨Í¨³£ÊÇ16룬°´»uÆ÷×Ö½Ú˳Ðo£(C)
S ¨C ²»´øÓÐ*uºÅµÄ¶Ìģʽ[short]£¨Í¨³£ÊÇ16룬°´»uÆ÷×Ö½ÚÅÅÐo£(C)
n -²»´øÓÐ*uºÅµÄ¶Ìģʽ[short]£¨Í¨³£ÊÇ16룬°´´oendian×Ö½ÚÅÅÐo£(C)
v -²»´øÓÐ*uºÅµÄ¶Ìģʽ[short]£¨Í¨³£ÊÇ16룬°´Ð¡endian×Ö½ÚÅÅÐo£(C)
i ¨C ´øÓÐ*uºÅµÄÕuÊý£¨ÓÉ´oСºÍ×Ö½Ú˳Ðo¾o¶¨£(C)
I ¨C ²»´øÓÐ*uºÅµÄÕuÊý£¨ÓÉ´oСºÍ×Ö½Ú˳Ðo¾o¶¨£(C)
l¨C ´øÓÐ*uºÅµÄ³¤Ä£Ê½[long]£¨Í¨³£ÊÇ32룬°´»uÆ÷×Ö½Ú˳Ðo£(C)
L ¨C ²»´øÓÐ*uºÅµÄ³¤Ä£Ê½[long]£¨Í¨³£ÊÇ32룬°´»uÆ÷×Ö½Ú˳Ðo£(C)
N ¨C ²»´øÓÐ*uºÅµÄ³¤Ä£Ê½[long]£¨Í¨³£ÊÇ32룬°´´oedian×Ö½Ú˳Ðo£(C)
V¨C ²»´øÓÐ*uºÅµÄ³¤Ä£Ê½[long]£¨Í¨³£ÊÇ32룬°´Ð¡edian×Ö½Ú˳Ðo£(C)
f ¨C¸¡µa£¨ÓÉ´oСºÍ×Ö½Ú˳Ðo¾o¶¨£(C)
d ¨C Ë«¾«¶È£¨ÓÉ´oСºÍ×Ö½Ú˳Ðo¾o¶¨£(C)
x ¨C ¿Õ×Ö½Ú[NUL byte]
X- ºoÃaeÒ»¸o×Ö½ÚBack up one byte
unpack
½aѹËoλ×Ö*u´®×ÊÁÏ¡£
Ói*¨: string pack(string format, mixed [args]...);
*µ»ØÖµ: Êý×e
±¾º¯ÊýÓÃÀ´½«Î»µÄ×Öu´®µÄ×ÊÁϽaѹËo¡£±¾º¯ÊýºÍ Perl µÄͬÃuº¯Êý¹¦ÄÜÓèÍeÈ«Ïaͬ¡£
°¸ÀýÒ»¡¢packʵÏÖËo¼oÎļþÊý¾Ý´ae´¢´oС
<?php
//´ae´¢ÕuÊý1234567890
file_put_contents("test.txt", 1234567890);
´Ëʱtest.txtµÄÎļþ´oСÊÇ10byte¡£×¢Òa´ËʱÎļþ´oСÊÇ10×Ö½Ú£¬Êµ¼ÊÕ¼Óÿռa´oСÊÇ1KB¡£
ÉÏÃae´ae´¢µÄÕuÊýʵ¼ÊÊÇÒÔ×Ö*u´®ÐÎʽ´ae´¢ÓÚÎļþtest.txtÖС£
µ«Èç¹uÒÔÕuÊýµÄ¶þ½øÖÆ×Ö*u´®´aejy´¢£¬½«»aËo¼oÖÁ4byte¡£
<?php
print_r(unpack("i", file_get_contents("test.txt")));
°¸Àý¶þ¡¢Êý¾Ý¼ÓÃÜ
ÒÔ×Ö*u´®ÐÎʽ´ae´¢Ò»¶ÎÓÐÒaÒaÊý¾Ý£¬7-110-abcdefg-117¡£
×Öu"-"Ö¸iºo£¬µÚһλ±iʾ×Öu´®³¤¶È£¬µÚ¶þλ±iʾ´ae´¢Î»Ö㬵ÚÈýλ±iʾʵ¼Ê´ae´¢µÄ×Öu´®£¬µÚËÄλ±iʾ½aβλÖá£
<?php
file_put_contents("test.txt", "7-110-abcdefg-117");
ÉÏÊo½¨È±µa£º
Ò»¡¢Êý¾Ý´ae´¢´oС
¶þ¡¢Êý¾ÝÒÔÃ÷ÎĽʽ´ae´¢£¬Èç¹uÊÇÈκÎÃo¸ÐÐÅÏ¢£¬¶¼¿ÉÄÜÔi³É²»°²È«ÃÎÊ¡£
Èý¡¢Îļþ´ae´¢´oС£¬ÒÔ²»¹aeÔo*½Ê½µÝÔo¡£
¼ÓÃÜ£º
<?php
file_put_contents("test.txt", pack("i2a7i1", 7, 110, "abcdefg", 117));
´ae´¢Ò»¶ÎÊý¾Ý£¬¼ÓÃܸñʽΪ£ºÕuÊý2볤¶È×Ö*u´®10볤¶ÈÕuÊý1볤¶È¡£
Óŵa£º
Ò»¡¢Êý¾Ý´oС×iÓÅ»¯
¶þ¡¢ÔÚ²»ÖªµÀ"i2a7i1"ÕaÑuµÄѹËo¸ñʽʱ£¬¼´Ê¹Äõ½Îļþ£¬Ò²ÎÞ¨ÕýȶÁ³o¶þ½øÖÆÎļþת»¯ÎªÃ÷ÎÄ¡£
Èý¡¢Êý¾ÝÔo¼Óʱ£¬Îļþ´ae´¢´oСÊǵÈÁ¿µÝÔo¡£Ã¿´Î¶¼ÊÇÒÔ19byteµÝÔo¡£
°¸ÀýÈý¡¢key-valueÐÍÎļþ´ae´¢
´ae´¢Éu³ÉµÄÎļþΪÁ½¸o£ºË÷ÒýÎļþ£¬Êý¾ÝÎļþ
ÎļþÖÐÊý¾Ý´ae´¢µÄ¸ñʽÈçÏÂͼ£º
´uÂeʵÏÖ£º
<?php
error_reporting(E_ALL);
class fileCacheException extends Exception{
}
//Key-ValueÐÍÎļþ´ae´¢
class fileCache{
private $_file_header_size = 14;
private $_file_index_name;
private $_file_data_name;
private $_file_index;//Ë÷ÒýÎļþ¾a±u
private $_file_data;//Êý¾ÝÎļþ¾a±u
private $_node_struct;//Ë÷Òý½aµa½a¹¹Ìa
private $_inx_node_size = 36;//Ë÷Òý½aµa´oС
public function __construct($file_index="filecache_index.dat", $file_data="filecache_data.dat"){
$this->_node_struct = array(
'next'=>array(1, 'V'),
'prev'=>array(1, 'V'),
'data_offset'=>array(1,'V'),//Êý¾Ý´ae´¢ÆðʼλÖÃ
'data_size'=>array(1,'V'),//Êý¾Ý³¤¶È
'ref_count'=>array(1,'V'),//ÒýÓô˴¦£¬Ä£*ÂPHPµÄÒýÓüÆÊýÏu»Ùģʽ
'key'=>array(16,'H*'),//´ae´¢KEY
);
$this->_file_index_name = $file_index;
$this->_file_data_name = $file_data;
if(!file_exists($this->_file_index_name)){
$this->_create_index();
}else{
$this->_file_index = fopen($this->_file_index_name, "rb+");
}
if(!file_exists($this->_file_data_name)){
$this->_create_data();
}else{
$this->_file_data = fopen($this->_file_data_name, "rb+");//¶þ½øÖÆ´ae´¢ÐeҪʹÓÃb
}
}
//´´½¨Ë÷ÒýÎļþ
private function _create_index(){
$this->_file_index = fopen($this->_file_index_name, "wb+");//¶þ½øÖÆ´ae´¢ÐeҪʹÓÃb
if(!$this->_file_index)
throw new fileCacheException("Could't open index file:".$this->_file_index_name);
$this->_index_puts(0, '<'.'?php exit()?'.'>');//¶¨Î»ÎļþÁ÷ÖÁÆðʼλÖÃ0, *ÅÖÃphp±e¼Ç*ÀÖ¹ÏÂÔØ
$this->_index_puts($this->_file_header_size, pack("V1", 0));
}
//´´½¨´ae´¢Îļþ
private function _create_data(){
$this->_file_data = fopen($this->_file_data_name, "wb+");//¶þ½øÖÆ´ae´¢ÐeҪʹÓÃb
if(!$this->_file_index)
throw new fileCacheException("Could't open index file:".$this->_file_data_name);
$this->_data_puts(0, '<'.'?php exit()?'.'>');//¶¨Î»ÎļþÁ÷ÖÁÆðʼλÖÃ0, *ÅÖÃphp±e¼Ç*ÀÖ¹ÏÂÔØ
}
private function _index_puts($offset, $data, $length=false){
fseek($this->_file_index, $offset);
if($length)
fputs($this->_file_index, $data, $length);
else
fputs($this->_file_index, $data);
}
private function _data_puts($offset, $data, $length=false){
fseek($this->_file_data, $offset);
if($length)
fputs($this->_file_data, $data, $length);
else
fputs($this->_file_data, $data);
}
/**
* ÎļþËø
* @param $is_block ÊÇ*ñ¶ÀÕ¼¡¢×eÈuËø
*/
private function _lock($file_res, $is_block=true){
flock($file_res, $is_block ? LOCK_EX : LOCK_EX|LOCK_NB);
}
private function _unlock($file_res){
flock($file_res, LOCK_UN);
}
public function add($key, $value){
$key = md5($key);
$value = serialize($value);
$this->_lock($this->_file_index, true);
$this->_lock($this->_file_data, true);
fseek($this->_file_index, $this->_file_header_size);
list(, $index_count) = unpack('V1', fread($this->_file_index, 4));
$data_size = filesize($this->_file_data_name);
fseek($this->_file_data, $data_size);
$value_size = strlen($value);
$this->_data_puts(filesize($this->_file_data_name), $value);
$node_data =
pack("V1V1V1V1V1H32", ($index_count==0) ? 0 : $index_count*$this->_inx_node_size, 0, filesize($this->_file_data_name), strlen($value), 0, $key);
$index_count++;
$this->_index_puts($this->_file_header_size, $index_count, 4);
$this->_index_puts($this->get_new_node_pos($index_count), $node_data);
$this->_unlock($this->_file_data);
$this->_unlock($this->_file_index);
}
public function get_new_node_pos($index_count){
return $this->_file_header_size + 4 + $this->_inx_node_size * ($index_count-1);
}
public function get_node($key){
$key = md5($key);
fseek($this->_file_index, $this->_file_header_size);
$index_count = fread($this->_file_index, 4);
if($index_count>0) {
for ($i=0; $i < $index_count ; $i++) {
fseek($this->_file_index, $this->_file_header_size + 4 + $this->_inx_node_size * $i);
$data = fread($this->_file_index, $this->_inx_node_size);
$node = unpack("V1next/V1prev/V1data_offset/V1data_size/V1ref_count/H32key", $data);
if($key == $node['key']){
return $node;
}
}
}else{
return null;
}
}
public function get_data($offset, $length){
fseek($this->_file_data, $offset);
return unserialize(fread($this->_file_data, $length));
}
}
//ʹÓÃ*½*¨
$cache = new fileCache();
$cache->add('abcdefg' , 'testabc');
$data = $cache->get_node('abcdefg');
print_r($data);
echo $cache->get_data($data['data_offset'], $data['data_size']);
°¸ÀýËÄ¡¢socketͨÐżÓÃÜ
ͨÐÅË«*½¶¼¶¨ÒaºÃ¼ÓÃܸñʽ:
ÀýÈ磺
$LOGIN = array(
'COMMAND'=>array('a30', 'LOGIN'),
'DATA'=>array('a30', 'HELLO')
);
$LOGOUT = array(
'COMMAND'=>array('a30', 'LOGOUT'),
'DATA'=>array('a30', 'GOOD BYE')
);
$LOGIN_SUCCESS = array(
'COMMAND'=>array('a30', 'LOGIN_SUCCESS'),
'DATA'=>array('V1', 1)
);
$LOGOUT_SUCCESS = array(
'COMMAND'=>array('a30', 'LOGIN_SUCCESS'),
'DATA'=>array('V1', time())
);
þÎñÆ÷¶ËÓe¿Í»§¶Ë¸u¾Ý½aÎoCOMMAND¸ñʽ£¬ÕÒµ½¶ÔÓ¦µÄDATA½aÂe½Ê½£¬µÃµ½ÕýÈ*µÄÊý¾Ý
ÒÔÉϾÍÊDZ¾ÎĵÄÈ«²¿ÄÚÈÝ£¬Ï£Íu¶Ô´o¼ÒµÄѧϰÓÐËu°iÖu£¬Ò²Ï£Íu´o¼Ò¶a¶aÖ§³Ö½Å±¾Ö®¼Ò¡£