最近在寫PHP的時候,須要使用內存緩存,你們都知道有比較成熟的基於memcached,redis,以及apc等緩存。可是不是要裝插件就是要第三方軟件支持。在小項目中用起來不是很方便!php
因此打算使用php的shared memory的shmop_*前綴的API來實現一個簡單的緩存接口。
此函數支持兩種調用方式,能夠設置和獲取緩存。設置的時候還能一併設置緩存過時時間。git
function cache($key, $val=null, $expire=100) { static $_caches = null; static $_shm = null; if ( null === $_shm ) $_shm = @shmop_open(crc32('mcache.solt'), 'c', 0755, config('cache.size', null, 10485760)); if ( null === $_caches && $_shm && ($size = intval(shmop_read($_shm, 0, 10)))) $_caches = $size ? @unserialize(@shmop_read($_shm, 10, $size)) : array(); if (($time = time()) && $val && $expire){ $_caches[$key] = array($time + intval($expire), $val); if($_shm && ($size = @shmop_write($_shm, serialize(array_filter($_caches, function($ n)use($time){return $n[0] > $time;})), 10))) @shmop_write($_shm, sprintf('%10d', $size), 0); return $val; } return (isset($_caches[$key]) && $_caches[$key][0] > $time) ? $_caches[$key][1] : null; }
不過有個缺點每次load cache的時候須要所有一塊兒load,而後反序列化保存到靜態數組裏面。只能緩存一些比較小的數據。若是數據過大會不能更新緩存。github
後來發現PHP還有提供一個操做shared memory的API,能夠使用這個API按照key value的形式存取緩存。這樣就避免了每次load所有緩存致使的多餘的開銷。redis
function shmcache($key, $val=null, $expire=100) { static $_shm = null; if ( null === $_shm ) $_shm = @shm_attach(crc32(config('mcache.solt', null, 'mcac he.solt')), config('cache.size', null, 10485760), 0755); if (($time = time()) && ($k = crc32($key)) && $val && $expire){ shm_put_var($_shm, $k, array($time + $expire, $val)); return $val; } return shm_has_var($_shm, $k) && ($data = shm_get_var($_shm, $k)) && $data[0] > $time ? $data[1] : null; }
我把這兩個函數和一些其餘的基本函數(如今只有9個函數)放在一個utils倉庫裏面。也能夠直接使用 composer require lloydzhou/utils 安裝數組