当前位置:Gxlcms > PHP教程 > 一个用mysql内存表来代替phpsession的类

一个用mysql内存表来代替phpsession的类

时间:2021-07-01 10:21:17 帮助过:27人阅读

  1. /**
  2. * session mysql内存表
  3. @Usage: use some other storage method(mysql or memcache) instead of php sessoin
  4. @author:lein
  5. @Version:1.2
  6. */
  7. session_start();
  8. if(!isset($_SESSION['test'])){
  9. $_SESSION['test']="123_lein_".date("Y-m-d H:i:s");
  10. }
  11. class session{
  12. //session data
  13. private $data;
  14. //engine,mysql or memcache
  15. private $engine;
  16. //php session expire time
  17. private $sessionexpiredTime;
  18. //current user's session cookie value
  19. private $sessionID;
  20. //session coolie name
  21. private $sessionCookieName;
  22. public function session($engineBase=NULL,$engineName='mysql',$storage_name='php_session'){
  23. try{
  24. $this->sessionexpiredTime = intval(ini_get("session.cache_expire"))*10;//默认是180分钟,太长了,改为了30分钟
  25. }catch(Exception $Exception){
  26. $this->sessionexpiredTime = 1200;
  27. }
  28. try{
  29. $this->sessionCookieName = ini_get("session.name");
  30. }catch(Exception $Exception){
  31. $this->sessionCookieName = 'PHPSESSID';
  32. }
  33. if(!isset($_COOKIE[$this->sessionCookieName])){
  34. @session_start();
  35. $this->sessionID=session_id();
  36. }else{
  37. $this->sessionID=$_COOKIE[$this->sessionCookieName];
  38. }
  39. $className = $engineName."SessionEngine";
  40. $this->engine = new $className(
  41. array(
  42. 'storage_name'=>$storage_name,//mysql table name or memcahce key which stores data;
  43. 'expire_time'=>$this->sessionexpiredTime,
  44. 'data_too_long_instead_value' => '{__DATA IS *$* TO LONG__}'
  45. ),
  46. $this->sessionID,
  47. &$engineBase
  48. );
  49. $this->init();
  50. $this->loadFromSession();
  51. $this->engine->refresh();
  52. $this->engine->cleanup();
  53. }
  54. private function init()
  55. {
  56. $this->data = $this->engine->get();
  57. if(empty($this->data)){
  58. @session_start();
  59. if(!empty($_SESSION)){
  60. $this->data = $_SESSION;
  61. $this->engine->create(false, $this->data);
  62. }
  63. else
  64. {
  65. $this->engine->create(false, "");
  66. }
  67. }
  68. }
  69. public function loadFromSession($flagStartSession = false){
  70. $flag=false;
  71. if($flagStartSession){
  72. @session_start();
  73. }
  74. if($_SESSION&&is_array($_SESSION)){
  75. foreach($_SESSION as $k=>$v){
  76. if(!isset($this->data[$k])){
  77. $this->data[$k] = $v;
  78. $flag=true;
  79. }
  80. }
  81. }
  82. if($flag){
  83. $this->engine->set(false, $this->data);
  84. }
  85. }
  86. private function __get($nm)
  87. {
  88. if (isset($this->data[$nm])) {
  89. $r = $this->data[$nm];
  90. return $r;
  91. }
  92. else
  93. {
  94. return NULL;
  95. }
  96. }
  97. private function __set($nm, $val)
  98. {
  99. $this->data[$nm] = $val;
  100. $this->engine->set(false, $this->data);
  101. }
  102. private function __isset($nm)
  103. {
  104. return isset($this->data[$nm]);
  105. }
  106. private function __unset($nm)
  107. {
  108. unset($this->data[$nm]);
  109. $this->engine->set(false, $this->data);
  110. }
  111. function __destruct(){
  112. $this->data = NULL;
  113. $this->engine->close();
  114. $this->engine = NULL;
  115. }
  116. }
  117. interface SessionEngine
  118. {
  119. /*
  120. * set varibles
  121. * @param $arr array,array(varible name=>varible value,...)
  122. */
  123. public function setVariable($arr);
  124. /*
  125. * get session value
  126. * @param $key string
  127. */
  128. public function get($key="");
  129. /*
  130. * set session value
  131. * @param $key string
  132. * @param $value string
  133. */
  134. public function set($key="",$value="");
  135. /*
  136. * set session value
  137. * @param $key string
  138. * @param $value string
  139. */
  140. public function create($key="",$value="");
  141. /*
  142. * update the session's invalid time
  143. * @param $key string
  144. */
  145. public function refresh($key="");
  146. /*
  147. * close mysql or memcache connection
  148. */
  149. public function close();
  150. /*
  151. * delete expired sessions
  152. */
  153. public function cleanup();
  154. }
  155. final class mysqlSessionEngine implements SessionEngine{
  156. private $id="";
  157. private $storage_name='php_session';
  158. private $storage_name_slow='php_session_slow';
  159. private $data_too_long_instead_value = '{__DATA IS ~ TO LONG__}';//if data is longer than $max_session_data_length and you are using mysql 4 or below,insert this value into memery table instead.
  160. private $expire_time=1200;
  161. private $max_session_data_length = 2048;
  162. private $conn;
  163. private $mysql_version;
  164. public function mysqlSessionEngine($arr=array(),$key="",&$_conn){
  165. $this->setVariable($arr);
  166. $this->id = $key;
  167. if(empty($this->id)||strlen($this->id)!=32){
  168. throw new Exception(__FILE__."->".__LINE__.": Session's cookie name can't be empty and it must have just 32 charactors!");
  169. }
  170. $this->conn = $_conn;
  171. if(!$this->conn||!is_resource($this->conn)){
  172. throw new Exception(__FILE__."->".__LINE__.": Need a mysql connection!");
  173. }
  174. $this->mysql_version = $this->getOne("select floor(version())");
  175. if($this->mysql_version<5){
  176. $this->max_session_data_length = 255;
  177. }
  178. }
  179. public function setVariable($arr){
  180. if(!empty($arr)&&is_array($arr)){
  181. foreach($arr as $k=>$v){
  182. $this->$k = $v;
  183. if($k=='storage_name'){
  184. $this->storage_name_slow = $v.'_slow';
  185. }
  186. }
  187. }
  188. }
  189. public function get($key=""){
  190. if($key=="") $key = $this->id;
  191. $return = $this->getOne('select value from '.$this->storage_name.' where id="'.$key.'"');
  192. if($return==$this->data_too_long_instead_value)
  193. {
  194. $return = $this->getOne('select value from '.$this->storage_name_slow.' where id="'.$key.'"');
  195. }
  196. if(!$return)
  197. {
  198. $mysqlError = mysql_error($this->conn);
  199. if(strpos($mysqlError,"doesn't exist")!==false)
  200. {
  201. $this->initTable();
  202. }
  203. $return = array();
  204. }
  205. else
  206. {
  207. $return = unserialize($return);
  208. }
  209. return $return;
  210. }
  211. public function close(){
  212. @mysql_close($this->conn);
  213. }
  214. public function cleanup(){
  215. if($this->mysql_version>4){
  216. $sql = 'delete from '.$this->storage_name.' where date_add(`time`,INTERVAL '.$this->expire_time.' SECOND) }else{
  217. $sql = 'delete from '.$this->storage_name_slow.' where `time`+'.$this->expire_time.' if($_SESSION['username']=="leinchu"){
  218. echo $sql;
  219. }
  220. $this->execute($sql);
  221. $sql = 'delete from '.$this->storage_name.' where `time`+'.$this->expire_time.' if($_SESSION['username']=="leinchu"){
  222. echo $sql;
  223. }
  224. }
  225. $this->execute($sql);
  226. }
  227. public function refresh($key=""){
  228. if($this->mysql_version>4){
  229. $sql = 'update '.$this->storage_name.' set `time`=CURRENT_TIMESTAMP() where id="'.$key.'"';
  230. }else{
  231. $sql = 'update '.$this->storage_name.' set `time`=unix_timestamp() where id="'.$key.'"';
  232. }
  233. $return = $this->execute($sql);
  234. if(!$return){
  235. $this->initTable();
  236. $return = $this->execute($sql,true);
  237. }
  238. return $return;
  239. }
  240. public function create($key="",$value=""){
  241. if($key=="") $key = $this->id;
  242. if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn);
  243. if(strlen($value)>$this->max_session_data_length)
  244. {
  245. if($this->mysql_version>4){
  246. throw new Exception(__FILE__."->".__LINE__.": Session data is long than max allow length(".$this->max_session_data_length.")!");
  247. }
  248. }
  249. if($this->mysql_version>4){
  250. $sql = 'replace into '.$this->storage_name.' set value=/''.$value.'/',id="'.$key.'",`time`=CURRENT_TIMESTAMP()';
  251. }else{
  252. $sql = 'replace into '.$this->storage_name.' set value=/''.$value.'/',id="'.$key.'",`time`=unix_timestamp()';
  253. }
  254. $return = $this->execute($sql);
  255. if(!$return){
  256. $this->initTable();
  257. $return = $this->execute($sql,true);
  258. }
  259. return $return;
  260. }
  261. public function set($key="",$value=""){
  262. if($key=="") $key = $this->id;
  263. if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn);
  264. $sql = 'update '.$this->storage_name.' set value=/''.$value.'/' where id="'.$key.'"';
  265. if(strlen($value)>$this->max_session_data_length)
  266. {
  267. if($this->mysql_version>4){
  268. throw new Exception(__FILE__."->".__LINE__.": Session data is long than max allow length(".$this->max_session_data_length.")!");
  269. }
  270. $sql = 'replace into '.$this->storage_name_slow.' set value=/''.$value.'/',id="'.$key.'",`time`=unix_timestamp()';
  271. $this->execute($sql,true);
  272. $sql = 'update '.$this->storage_name.' set value=/''.$this->data_too_long_instead_value.'/' where id="'.$key.'"';
  273. }
  274. $return = $this->execute($sql);
  275. if(!$return){
  276. $this->initTable();
  277. $return = $this->execute($sql,true);
  278. }
  279. return $return;
  280. }
  281. private function initTable(){
  282. if($this->mysql_version>4){
  283. $sql = "
  284. CREATE TABLE if not exists `".$this->storage_name."` (
  285. `id` char(32) NOT NULL default 'ERR',
  286. `value` VARBINARY(".$this->max_session_data_length.") NULL,
  287. `time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  288. PRIMARY KEY (`id`),
  289. KEY `time` (`time`)
  290. ) ENGINE=MEMORY;
  291. ";
  292. }else{
  293. $sqlSlow = "
  294. CREATE TABLE if not exists `".$this->storage_name."_slow` (
  295. `id` char(32) NOT NULL default 'ERR',
  296. `value` text NULL,
  297. `time` int(10) not null default '0',
  298. PRIMARY KEY (`id`),
  299. KEY `time` (`time`)
  300. ) ENGINE=MyISAM;
  301. ";
  302. $this->execute($sqlSlow,true);
  303. $sql = "
  304. CREATE TABLE if not exists `".$this->storage_name."` (
  305. `id` char(32) NOT NULL default 'ERR',
  306. `value` VARCHAR(255) NULL,
  307. `time` int(10) not null default '0',
  308. PRIMARY KEY (`id`),
  309. KEY `time` (`time`)
  310. ) ENGINE=MEMORY;
  311. ";
  312. }
  313. return $this->execute($sql,true);
  314. }
  315. private function execute($sql,$die=false)
  316. {
  317. if($die)
  318. {
  319. mysql_query($sql,$this->conn) or die("exe Sql error:
    ".mysql_error()."
    ".$sql."
    ");
  320. }
  321. else
  322. {
  323. mysql_query($sql,$this->conn);
  324. if(mysql_error()){
  325. return false;
  326. }else{
  327. return true;
  328. }
  329. }
  330. }
  331. private function getOne($sql,$die=false){
  332. $rs = $this->query($sql,$die);
  333. if($rs && ($one = mysql_fetch_row($rs)) ){
  334. return $one[0];
  335. }else{
  336. return false;
  337. }
  338. }
  339. private function query($sql,$die=false){
  340. if($die)
  341. $rs = mysql_query($sql,$this->conn) or die("query Sql error:
    ".mysql_error()."
    ".$sql."
    ");
  342. else
  343. $rs = mysql_query($sql,$this->conn);
  344. return $rs;
  345. }
  346. }
  347. $lnk = mysql_connect('localhost', 'root', '123456')
  348. or die ('Not connected : ' . mysql_error());
  349. // make foo the current db
  350. mysql_select_db('test', $lnk) or die ('Can/'t use foo : ' . mysql_error());
  351. $S = new session($lnk);
  352. if(!$S->last){
  353. $S->last = time();
  354. }
  355. echo "First visit at ".$S->last."
    ";
  356. if(!$S->lastv){
  357. $S->lastv = 0;
  358. }
  359. $S->lastv++;
  360. echo "lastv=".$S->lastv."
    ";
  361. echo "test=".$S->test."
    ";
  362. if(isset($_GET['max'])){
  363. $S->boom = str_repeat("OK",255);
  364. }
  365. if(isset($_GET['boom'])){
  366. $S->boom = $_GET['boom'];
  367. }
  368. echo "boom=".$S->boom."
    ";
  369. ?>

人气教程排行