MySQLメモリテーブルを使用してPHPセッションを置き換えるクラス

WBOY
リリース: 2016-07-25 08:57:23
オリジナル
811 人が閲覧しました
  1. /**
  2. * session mysql内存表
  3. @Usage: php sessoinの代わりに他のストレージメソッド(mysqlまたはmemcache)を使用してください
  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. //セッションデータ
  13. private $data;
  14. //engine、mysql または memcache
  15. private $engine;
  16. //php セッションの有効期限
  17. private $sessionexpiredTime;
  18. //現在のユーザーのセッション Cookie 値
  19. private $sessionID;
  20. //セッションクーリー名
  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 テーブル名または memcahce キー;
  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. プライベート関数 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. パブリック関数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 ->データ[$k] = $v;
  78. $flag=true;
  79. }
  80. }
  81. }
  82. if($flag){
  83. $this->engine->set(false, $this->data);
  84. }
  85. }
  86. プライベート関数 __get($nm)
  87. {
  88. if (isset($this->data[$nm])) {
  89. $r = $this->data[$nm];
  90. $r を返します;
  91. }
  92. else
  93. {
  94. NULL を返す;
  95. }
  96. }
  97. プライベート関数 __set($nm, $val)
  98. {
  99. $this->data[$nm] = $val;
  100. $this->engine->set(false, $this->data);
  101. }
  102. プライベート関数 __isset($nm)
  103. {
  104. return isset($this->data[$nm]);
  105. }
  106. プライベート関数 __unset($nm)
  107. {
  108. unset($this->data[$nm]);
  109. $this->engine->set(false, $this->data);
  110. }
  111. 関数 __destruct(){
  112. $this->data = NULL;
  113. $this->engine->close();
  114. $this->engine = NULL;
  115. }
  116. }
  117. interface SessionEngine
  118. {
  119. /*
  120. * 変数を設定
  121. * @param $arr array,array(variable name=>variable value,...)
  122. */
  123. public function setVariable($arr);
  124. /*
  125. * セッション値を取得
  126. * @param $key string
  127. */
  128. public function get($key="");
  129. /*
  130. * セッション値を設定します
  131. * @param $key string
  132. * @param $value string
  133. */
  134. public function set($key="",$value="");
  135. /*
  136. * セッション値を設定します
  137. * @param $key string
  138. * @param $value string
  139. */
  140. public function create($key="",$value="");
  141. /*
  142. * セッションの無効な時間を更新します
  143. * @param $key string
  144. */
  145. public functionfresh($key="");
  146. /*
  147. * mysql または memcache 接続を閉じる
  148. */
  149. public function close();
  150. /*
  151. * 期限切れのセッションを削除します
  152. */
  153. public function cleanup();
  154. }
  155. final クラス mysqlSessionEngine は SessionEngine{
  156. private $id=""; を実装します。
  157. プライベート $storage_name='php_session';
  158. プライベート $storage_name_slow='php_session_slow';
  159. private $data_too_long_instead_value = '{__DATA IS ~ TO LONG__}';//データが $max_session_data_length より長く、mysql 4 以下を使用している場合は、代わりにこの値をメモリ テーブルに挿入します。
  160. プライベート $expire_time=1200;
  161. プライベート $max_session_data_length = 2048;
  162. プライベート $conn;
  163. プライベート $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__.": セッションの Cookie 名はできません空ではなく、文字数は 32 文字だけでなければなりません!");
  169. }
  170. $this->conn = $_conn;
  171. if(!$this->conn||!is_resource($this->conn)){
  172. throw new Exception(__FILE__."->".__LINE__.": MySQL 接続が必要です!");
  173. }
  174. $this->mysql_version = $this->getOne("select Floor(version())");
  175. if($this->mysql_version $this->max_session_data_length = 255;
  176. }
  177. }
  178. public function setVariable($arr){
  179. if(!empty($arr)&&is_array($arr)){
  180. foreach($arr as $k=>$v){
  181. $this-> $k = $v;
  182. if($k=='ストレージ名'){
  183. $this->ストレージ名_slow = $v.'_slow';
  184. }
  185. }
  186. }
  187. }
  188. public function get($key=""){
  189. if($key=="") $key = $this->id;
  190. $return = $this->getOne('select value from '.$this->storage_name.' where id="'.$key.'"');
  191. if($return==$this->data_too_long_instead_value)
  192. {
  193. $return = $this->getOne('select value from '.$this->storage_name_slow.' where id="'.$key. '"');
  194. }
  195. if(!$return)
  196. {
  197. $mysqlError = mysql_error($this->conn);
  198. if(strpos($mysqlError,"存在しません")!==false)
  199. {
  200. $this->initTable();
  201. }
  202. $return = array();
  203. }
  204. else
  205. {
  206. $return = unserialize($return);
  207. }
  208. return $return;
  209. }
  210. パブリック関数 close(){
  211. @mysql_close($this->conn);
  212. }
  213. public function cleanup(){
  214. if($this->mysql_version>4){
  215. $sql = '.$this->storage_name から削除します。' where date_add(`time`,INTERVAL '.$this->expire_time.' SECOND) }else{
  216. $sql = '.$this->storage_name_slow.' から削除します。ここで、 `time`+'.$this->expire_time.' if($_SESSION['username']=="ラインチュ"){
  217. echo $sql;
  218. }
  219. $this->execute($sql);
  220. $sql = '.$this->storage_name から削除します。'ここで、 `time`+'.$this->expire_time.' if($_SESSION['username']=="ラインチュ"){
  221. echo $sql;
  222. }
  223. }
  224. $this->execute($sql);
  225. }
  226. public function reports($key=""){
  227. if($this->mysql_version>4){
  228. $sql = 'update '.$this->storage_name.' set `time`=CURRENT_TIMESTAMP() where id="'.$key.'"';
  229. }else{
  230. $sql = '更新'.$this->storage_name.' set `time`=unix_timestamp() where id="'.$key.'"';
  231. }
  232. $return = $this->execute($sql);
  233. if(!$return){
  234. $this->initTable();
  235. $return = $this->execute($sql,true);
  236. }
  237. return $return;
  238. }
  239. public function create($key="",$value=""){
  240. if($key=="") $key = $this->id;
  241. if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn);
  242. if(strlen($value)>$this->max_session_data_length)
  243. {
  244. if($this->mysql_version>4){
  245. throw new Exception(__FILE__."->".__LINE__.": セッションデータが最大許容長を超えています(".$this->max_session_data_length.")!");
  246. }
  247. }
  248. if($this->mysql_version>4){
  249. $sql = '.$this->storage_name.' に置き換えます。 set value=/''.$value.'/',id="'.$key.'",`time`=CURRENT_TIMESTAMP()';
  250. }else{
  251. $sql = '.$this->storage_name.' に置き換えます。 set value=/''.$value.'/',id="'.$key.'",`time`=unix_timestamp()';
  252. }
  253. $return = $this->execute($sql);
  254. if(!$return){
  255. $this->initTable();
  256. $return = $this->execute($sql,true);
  257. }
  258. return $return;
  259. }
  260. public function set($key="",$value=""){
  261. if($key=="") $key = $this->id;
  262. if($value != "") $value = mysql_real_escape_string(serialize($value),$this->conn);
  263. $sql = '更新'.$this->storage_name.' set value=/''.$value.'/' where id="'.$key.'"';
  264. if(strlen($value)>$this->max_session_data_length)
  265. {
  266. if($this->mysql_version>4){
  267. throw new Exception(__FILE__."->".__LINE__.": セッションデータが最大許容長を超えています(".$this->max_session_data_length.")!");
  268. }
  269. $sql = '.$this->storage_name_slow.' に置き換えます。 set value=/''.$value.'/',id="'.$key.'",`time`=unix_timestamp()';
  270. $this->execute($sql,true);
  271. $sql = '更新'.$this->storage_name.' set value=/''.$this->data_too_long_instead_value.'/' where id="'.$key.'"';
  272. }
  273. $return = $this->execute($sql);
  274. if(!$return){
  275. $this->initTable();
  276. $return = $this->execute($sql,true);
  277. }
  278. return $return;
  279. }
  280. プライベート関数 initTable(){
  281. if($this->mysql_version>4){
  282. $sql = "
  283. 存在しない場合は CREATE TABLE `".$this->storage_name."` (
  284. `id` char(32) NOT NULL デフォルト 'ERR'、
  285. `value` VARBINARY(".$this->max_session_data_length.") NULL、
  286. `time` タイムスタンプ NOT NULL 更新時のデフォルト CURRENT_TIMESTAMP CURRENT_TIMESTAMP、
  287. PRIMARY KEY (`id` ),
  288. KEY `time` (`time`)
  289. ) ENGINE=MEMORY
  290. ";
  291. }else{
  292. $sqlSlow = "
  293. 存在しない場合はテーブルを作成します `".$this->storage_name."_slow` (
  294. `id` char(32) NOT NULL デフォルト 'ERR',
  295. `value` text NULL ,
  296. `time` int(10) not null デフォルト '0',
  297. PRIMARY KEY (`id`),
  298. KEY `time` (`time`)
  299. ) ENGINE=MyISAM
  300. ";
  301. $this->execute($sqlSlow,true);
  302. $sql = "
  303. 存在しない場合はテーブルを作成します `".$this->storage_name."` (
  304. `id` char(32) NOT NULL デフォルト 'ERR',
  305. `value` VARCHAR(255) NULL,
  306. `time` int(10) not null デフォルト '0',
  307. PRIMARY KEY (`id`),
  308. KEY `time` (`time`)
  309. ) ENGINE=MEMORY
  310. ";
  311. }
  312. return $this->execute($sql,true);
  313. }
  314. プライベート関数execute($sql,$die=false)
  315. {
  316. if($die)
  317. {
  318. mysql_query($sql,$this->conn) または die("exe Sql error:
    ". mysql_error()."
    ".$sql."
    ");
  319. }
  320. else
  321. {
  322. mysql_query($sql,$this->conn);
  323. if(mysql_error()){
  324. false を返します。
  325. }else{
  326. true を返します。
  327. }
  328. }
  329. }
  330. プライベート関数 getOne($sql,$die=false){
  331. $rs = $this->query($sql,$die);
  332. if($rs && ($one = mysql_fetch_row($rs)) ){
  333. return $one[0];
  334. }else{
  335. false を返します。
  336. }
  337. }
  338. プライベート関数 query($sql,$die=false){
  339. if($die)
  340. $rs = mysql_query($sql,$this->conn) または die("クエリ SQL エラー:< br>".mysql_error()."
    ".$sql."
    ");
  341. else
  342. $rs = mysql_query($sql,$this->conn);
  343. $rs を返します;
  344. }
  345. }
  346. $lnk = mysql_connect('localhost', 'root', '123456')
  347. or die ('接続されていません : ' .mysql_error());
  348. // foo を現在のデータベースにする
  349. mysql_select_db('test', $lnk) or die ('Can/'t use foo : ' . mysql_error());
  350. $S = 新しいセッション($lnk);
  351. if(!$S->last){
  352. $S->last = time();
  353. }
  354. echo "「.$S->last」に初めて訪問しました。
    ";
  355. if(!$S->lastv){
  356. $S->lastv = 0;
  357. }
  358. $S->lastv++;
  359. echo "lastv=".$S->lastv."
    ";
  360. echo "test=".$S->test."
    ";
  361. if(isset($_GET['max'])){
  362. $S->boom = str_repeat("OK",255);
  363. }
  364. if(isset($_GET['ブーム'])){
  365. $S->ブーム = $_GET['ブーム'];
  366. }
  367. echo "boom=".$S->boom."
    ";
  368. ?>
复制代


ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!