首頁  >  文章  >  後端開發  >  一個用mysql記憶體表來取代php session的類

一個用mysql記憶體表來取代php session的類

WBOY
WBOY原創
2016-07-25 08:57:23818瀏覽
  1. /**
  2. * session mysql 內存表
  3. @Usage: 使用其他儲存方法(mysql 或 memcache)取代 php sessoin
  4. @author:lein
  5. @Version:1.2
  6. */
  7. session_start();
  8. if(!isset($_SESSION['testsession_start();
  9. if(!isset($_SESSION['testses'' ])){
  10. $_SESSION['test']="123_lein_".date("Y-m-d H:i:s");
  11. }
  12. class session{
  13. //會話資料
  14. private $data;
  15. //引擎,mysql或memcache
  16. private $engine;
  17. //php 會話過期時間
  18. private $sessionexpiredTime;
  19. 當前使用者的會話 // cookie值
  20. private $sessionID;
  21. //會話苦力名稱
  22. private $sessionCookieName;
  23. public function session($engineBase=NULL,$engineName='mysql',$storage_name='php_session') {
  24. try{
  25. $this->sessionexpiredTime = intval(ini_get("session.cache_expire) "))*10;//預設是180分鐘,太長了,改為了30分鐘
  26. }catch (Exception $Exception){
  27. $this->sessionexpiredTime = 1200;
  28. }
  29. 嘗試{
  30. $this->sessionCookieName = ini_get("session.name");
  31. }catch( Exception $Exception){
  32. $this->sessionCookieName = 'PHPSESSID';
  33. }
  34. if(!isset($_COOKIE[$this->sessionCookieName])){
  35. @session_start ();
  36. $this->sessionID=session_id();
  37. }else{
  38. $this->sessionID=$_COOKIE[$this->sessionCookieName];
  39. }
  40. $className = $engineName."SessionEngine";
  41. $this->engine = new $className(
  42. array(
  43. 'storage_name'=>$storage_name,//儲存資料的mysql表名或memcahce鍵;
  44. 'expire_time'= >$this->sessionexpiredTime,
  45. 'data_too_long_instead_value' => '{__DATA IS *$* TO LONG__}'
  46. ),
  47. $this->sessionID,
  48. $engineBase
  49. );
  50. $this->init();
  51. $this->loadFromSession();
  52. $this->engine->refresh();
  53. $this-> engine->cleanup();
  54. }
  55. 私有函數init()
  56. {
  57. $this->data = $this->engine->get();
  58. if(empty( $this->data)){
  59. @session_start();
  60. if(!empty($_SESSION)){
  61. $this->data = $_SESSION;
  62. $this->engine- >create(false, $this->data);
  63. }
  64. else
  65. {
  66. $this->engine->create(false, "");
  67. }
  68. }
  69. }
  70. public function loadFromSession($flagStartSession = false){
  71. $flag=false;
  72. if($flagStartSession){
  73. @session_start(); ($_SESSION&&is_array($_SESSION)){
  74. foreach($_SESSION as $k=>$v){
  75. if(!isset($this->data[$ k])){
  76. $this ->data[$k] = $v;
  77. $flag=true;
  78. }
  79. }
  80. }
  81. if($flag){
  82. $this->engine-> set(false, $this->data);
  83. }
  84. }
  85. 私有函數__get($nm)
  86. {
  87. if (isset($this->data[$nm] )) {
  88. $r = $this -> 資料[$nm];
  89. 回傳$r;
  90. }
  91. else
  92. {
  93. 回傳NULL;
  94. }
  95. }
  96. 私有函數__set($nm, $val)
  97. {
  98. $this->data[$nm] = $val;
  99. $this->engine->set(false, $this->data);
  100. }
  101. 私有函數__isset($nm)
  102. {
  103. return isset($this->data[$nm]);
  104. }
  105. 私有函數__unset($nm)
  106. {
  107. unset($this->data[$nm]);
  108. $this->engine->set(false, $this ->data);
  109. }
  110. function __destruct(){
  111. $this->data = NULL;
  112. $this->engine->close();
  113. $this ->engine = NULL;
  114. }
  115. }
  116. 介面SessionEngine
  117. {
  118. /*
  119. * 設定變數
  120. * @param $arr array,array(變數名稱=>變數值,...)
  121. * /
  122. public function setVariable($arr);
  123. /*
  124. * 取得會話值
  125. * @param $key string
  126. */
  127. public function get($key="" );
  128. /*
  129. * 設定會話值
  130. * @param $key 字串
  131. * @param $value 字串
  132. */
  133. public function set($key=" ",$value =“”);
  134. /*
  135. * 設定會話值
  136. * @param $key 字串
  137. * @param $value 字串
  138. */
  139. public function create($key="",$value =");
  140. /*
  141. * 更新會話的無效時間
  142. * @param $key string
  143. */
  144. public function refresh ($key="");
  145. /*
  146. * 關閉mysql 或memcache 連線
  147. */
  148. public function close();
  149. /*
  150. * 刪除過期會話
  151. */
  152. public function cleanup();
  153. }
  154. 最終類別mysqlSessionEngine 實作SessionEngine{
  155. private $id="";
  156. private $storage_name='_session'; 🎜> private $storage_name_slow='php_session_slow';
  157. private $data_too_long_instead_value = '{__DATA IS ~ TO LONG__}';//如果資料長於$max_session_data_length 是此版本插入到內存表中。
  158. 私人$expire_time=1200;
  159. 私人$max_session_data_length = 2048;
  160. 私人$conn;
  161. 私人$mysql_version;
  162. public function my="SarraionEngine($mysql=$ ",&$_conn){
  163. $this->setVariable($arr);
  164. $this->id = $key;
  165. if(empty($this->id)||strlen($ this->id)!=32){
  166. throw new Exception(__FILE__."->".__LINE__.": 會話的cookie 名稱不能為空,且必須只有32 個字元!");
  167. }
  168. $this->conn = $_conn;
  169. if(!$this->conn||!is_resource($this->conn)){
  170. throw new Exception(__FILE__."->". __LINE__.": 需要mysql 連線!」);
  171. }
  172. $this->mysql_version = $this->getOne(" 選取樓層(version())");
  173. if($this-> mysql_version $this->max_session_data_length = 255;
  174. }
  175. }
  176. public function setVariable($arr){
  177. if(!empty($arr)&arr_x )){
  178. foreach($arr as $k=>; $v){
  179. $this->$k = $v;
  180. if($k=='storage_name'){
  181. $this->storage_name_slow = $v.'_slow';
  182. }
  183. }
  184. }
  185. }
  186. public function get($key=""){
  187. if($key =="") $key = $this->; ID;
  188. $return = $this->getOne('從'.$this->storage_name.' 中選取值,其中id="'.$key .'"');
  189. if($return==$this->data_too_long_instead_value)
  190. {
  191. $return = $this->getOne(' 從'.$this->storage_name_slow.' 中選擇值。 ' 其中id= "'.$key.'"');
  192. }
  193. if(!$return)
  194. {
  195. $mysqlError = mysql_error($this->conn);
  196. if(strpos($mysqlError,"不存在")!==false)
  197. {
  198. $this->initTable();
  199. }
  200. $return = array();
  201. }
  202. else
  203. {
  204. $return = unserialize($return);
  205. }
  206. 回傳$return;
  207. }
  208. public function close(){
  209. }
  210. public function close(){
  211. $this->conn);
  212. }
  213. public function cleanup(){
  214. if($this->mysql_version>4){
  215. $sql = '從'.$this->storage_name 中刪除。 '其中 date_add(`time`,INTERVAL '.$this->expire_time.' SECOND) }else{
  216. $sql = '從 '.$this->storage_name_slow 中刪除。 '其中`time`+'.$this->expire_time.' if($_SESSION['username']=="leinchu"){
  217. echo $sql;
  218. }
  219. $this->execute($sql);
  220. $sql = '從'.$this->storage_name 移除。 '其中`time`+'.$this->expire_time.' if($_SESSION['username']=="leinchu"){
  221. echo $sql;
  222. }
  223. }
  224. $this->execute($sql); }
  225. public function refresh($key=""){
  226. if($this->mysql_version>4){
  227. $sql = 'update '.$this->storage_name.' 設定 `time`= CURRENT_TIMESTAMP() 其中id="'.$key.'"';
  228. }else{
  229. $sql = '更新 '.$this->storage_name.' 設定 `time`=unix_timestamp() where id="'.$key.'"';
  230. }
  231. $return = $this->execute($sql);
  232. if(!$return){
  233. $this->initTable();
  234. $return = $this->execute($sql,true);
  235. }
  236. 回傳 $return;
  237. }
  238. public function create($key="",$value=""){
  239. if($key=="") $key = $this->id;
  240. if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn);
  241. if(strlen($value)>$this->max_session_data_length)
  242. {
  243. if($this->mysql_version>4){
  244. 拋出新的例外(__FILE__."-> ; ". __LINE__.": 會話資料長度超過最大允許長度(".$this->max_session_data_length.")!");
  245. }
  246. }
  247. if($this->mysql_version>4){
  248. $sql = '替換為'.$this->storage_name.'設定 value=/''.$value。 '/',id="'.$key.'",`time`=CURRENT_TIMESTAMP()';
  249. }else{
  250. $sql = '替換為'.$this->storage_name。時間`=unix_timestamp()';
  251. }
  252. $return = $this->execute($sql);
  253. if(!$return){
  254. $this->initTable();
  255. $return = $this->execute($sql,true);
  256. }
  257. 回傳 $return;
  258. }
  259. public function set($key="",$value=""){
  260. if($key=="") $key = $this->id;
  261. if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn);
  262. $sql = '更新'.$this->storage_name.'設定 value=/''.$value.'/' where id="'.$key.'"';
  263. if(strlen($value)>$this->max_session_data_length)
  264. {
  265. if($this->mysql_version>4){
  266. 拋出新的例外(__FILE__."-> ; ". __LINE__.": 會話資料長度超過最大允許長度(".$this->max_session_data_length.")!");
  267. }
  268. $sql = '替換為'.$this->storage_name_slow。 =unix_timestamp()';
  269. $this->execute($sql,true);
  270. $sql = '更新'.$this->儲存名稱。 '設定 value=/''.$this->data_too_long_instead_value.'/' 其中 id="'.$key.'"';
  271. }
  272. $return = $this->execute($sql);
  273. if(!$return){
  274. $this->initTable();
  275. $return = $this->execute($sql,true);
  276. }
  277. 回傳 $return;
  278. }
  279. private function initTable(){
  280. if($this->mysql_version>4){
  281. $sql = "
  282. 如果不存在則建立表格 `".$this-> "` (
  283. `id` char(32) NOT NULL 預設'ERR',
  284. `value` VARBINARY(".$this->max_session_data_length.") NULL,
  285. `time`CURRENT_TIMESTAMP 時的計時器不為NULL 預設CURRENT_TIMESTAMP,
  286. PRIMARY KEY (`id`),
  287. KEY `time` (`time`)
  288. ) ENGINE=MEMORY> ";
  289. }else{
  290. $sqlSlow = "
  291. 如果不存在則建立表格 `".$this->storage_name."_slow` (
  292. `id` char(32) NOT NULL default 'ERR ',
  293. `value` text NULL,
  294. `time` int(10) not null default '0',
  295. PRIMARY KEY (`id`),
  296. KEY `time` (`time` )
  297. ) ENGINE=MyISAM;
  298. ";
  299. $this->execute($sqlSlow,true);
  300. $sql = "
  301. 如果不存在則建立表格 `".$this->storage_name."` (
  302. `id` char(32) NOT NULL 預設 'ERR',
  303. `value` VARCHAR(255) NULL,
  304. `time` int(10) not null default '0',
  305. PRIMARY KEY (`id`),
  306. KEY `time` (`time`)
  307. ) 引擎=記憶體;
  308. }
  309. return $this->execute($sql,true);
  310. }
  311. 初始函數execute($sql,$die=false)
  312. {
  313. if($die)
  314. {
  315. mysql_query($sql,$this->conn) or die(" exeor Sql 錯誤:
    ".mysql_error()."
    ".$sql."
    ");
  316. }
  317. else
  318. {
  319. mysql_query($sql,$this->conn);
  320. if(mysql_error()){
  321. return false;
  322. }else{
  323. 回傳 true;
  324. }
  325. }
  326. }
  327. private function getOne($sql,$die=false){
  328. $rs = $this->查詢($sql,$die);
  329. if($rs && ($one = mysql_fetch_row($rs)) ){
  330. return $one[0];
  331. }else{
  332. 回傳 false;
  333. }
  334. }
  335. 乾燥函數查詢($sql,$die=false){
  336. if($die)
  337. $rs = mysql_query($sql,$this->conn) or die("查詢Sql錯誤:
    ".mysql_error()."
    ".$sql."
    ");
  338. else
  339. $rs = mysql_query($sql,$this->conn);
  340. 回傳 $rs;
  341. }
  342. }
  343. $lnk = mysql_connect('localhost', 'root', '123456')
  344. 或 die ('未連線: ' .mysql_error());
  345. // 使 foo 成為目前資料庫
  346. mysql_select_db('test', $lnk) 或 die ('Can/'t use foo : ' . mysql_error());
  347. $S = 新會話($lnk);
  348. if(!$S->last){
  349. $S->last = time();
  350. }
  351. echo "第一次造訪於 ".$S->last."
    ";
  352. if(!$S->lastv){
  353. $S->lastv = 0;
  354. }
  355. $S->lastv++;
  356. echo "lastv=".$S->lastv."
    ";
  357. echo "test=".$S->test."
    ";
  358. if(isset($_GET['max'])){
  359. $S->boom = str_repeat("OK",255);
  360. }
  361. if(isset($_GET['boom'])){
  362. $S->boom = $_GET['boom'];
  363. }
  364. echo "boom=".$S->boom."
    ";
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn