session.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 16/1/30
  6. * Time: 下午3:43
  7. */
  8. class session
  9. {
  10. static $stInstance = NULL;
  11. private $fdestroy = false;
  12. private $sessid = '';
  13. const prefix = 'MPHPSESSID';
  14. const session_name = 'MPHPSESSID';
  15. static public function instance()
  16. {
  17. if(self::$stInstance == NULL) {
  18. self::$stInstance = new session();
  19. }
  20. return self::$stInstance;
  21. }
  22. private function __construct()
  23. {
  24. }
  25. public function init()
  26. {
  27. session_set_save_handler(
  28. array(&$this,'onOpen'),
  29. array(&$this,'onClose'),
  30. array(&$this,'onRead'),
  31. array(&$this,'onWrite'),
  32. array(&$this,'onDestroy'),
  33. array(&$this,'onGc'));
  34. }
  35. public function start()
  36. {
  37. $this->fdestroy = false;
  38. session_start();
  39. $_SESSION['MPHPSESSID'] = $this->sessid;
  40. }
  41. public function end()
  42. {
  43. // 会触发write 和 close 函数
  44. session_write_close();
  45. foreach($_SESSION as $key=>$value) {
  46. unset($_SESSION[$key]);
  47. }
  48. foreach($_COOKIE as $key=>$value) {
  49. unset($_COOKIE[$key]);
  50. }
  51. foreach($_POST as $key => $value) {
  52. unset($_POST[$key]);
  53. }
  54. foreach($_GET as $key => $value) {
  55. unset($_GET[$key]);
  56. }
  57. request_helper::clear_server();
  58. $this->sessid = '';
  59. }
  60. public function destroy() {
  61. $this->fdestroy = true;
  62. $sid = $this->sessid;
  63. if(is_localdebug()) {
  64. fcgi_setcookie("MPHPSESSID","{$sid}", -3600,'/',LOCAL_DOMAIN);
  65. } else {
  66. fcgi_setcookie("MPHPSESSID","{$sid}", -3600,'/','.lrlz.com');
  67. }
  68. }
  69. public function onOpen() {
  70. return true;
  71. }
  72. public function onRead($rsid)
  73. {
  74. //这段代码为了确保内置H5,直接使用客户端的session 状态。
  75. $client = strtolower(trim($_SERVER['HTTP_CLIENT_TYPE']));
  76. if($client == 'ios' || $client == 'android')
  77. {
  78. $sid = $_COOKIE[self::session_name];
  79. Log::record("APP MPHPSESSID = {$sid}." , Log::DEBUG);
  80. return $this->from_certain($sid);
  81. }
  82. else
  83. {
  84. $sid = $_COOKIE[self::session_name];
  85. Log::record("WAP MPHPSESSID = {$sid}." , Log::DEBUG);
  86. if(isset($_POST['HPHPSESSID']) && !empty($_POST['HPHPSESSID']))
  87. {
  88. $hsid = $_POST['HPHPSESSID'];
  89. $this->sessid = $hsid;
  90. if($sid == $hsid) {
  91. return $this->from_certain($sid);
  92. } else {
  93. return $this->from_uncertain($hsid);
  94. }
  95. }
  96. else
  97. {
  98. return $this->from_certain($sid);
  99. }
  100. }
  101. }
  102. private function from_uncertain($sid)
  103. {
  104. //$this->set_cookie($sid);
  105. if(empty($sid))
  106. {
  107. return '';
  108. }
  109. else
  110. {
  111. $data = rcache($sid,self::prefix);
  112. if(empty($data)) {
  113. return '';
  114. } else {
  115. $this->sessid = $sid;
  116. return $data[self::session_name];
  117. }
  118. }
  119. }
  120. private function from_certain($sid)
  121. {
  122. if(empty($sid))
  123. {
  124. $ret = session_regenerate_id(false);
  125. if($ret == true) {
  126. $sid = session_id();
  127. $this->set_cookie($sid);
  128. $this->sessid = $sid;
  129. } else {
  130. Log::record("session_regenerate_id error.",Log::ERR);
  131. }
  132. return '';
  133. }
  134. else
  135. {
  136. $data = rcache($sid,self::prefix);
  137. if(empty($data))
  138. {
  139. dcache($sid,self::prefix);
  140. $ret = session_regenerate_id(false);
  141. if($ret == true) {
  142. $sid = session_id();
  143. $this->set_cookie($sid);
  144. $this->sessid = $sid;
  145. } else {
  146. Log::record("session_regenerate_id error.",Log::ERR);
  147. }
  148. return '';
  149. } else {
  150. $this->sessid = $sid;
  151. return $data[self::session_name];
  152. }
  153. }
  154. }
  155. public function onClose() {
  156. return true;
  157. }
  158. public function onWrite($sid, $data)
  159. {
  160. if($this->fdestroy) {
  161. dcache($this->sessid,self::prefix);
  162. } else {
  163. wcache($this->sessid,array(self::session_name => $data),self::prefix,self::expire_min());
  164. }
  165. return true;
  166. }
  167. public function onDestroy($sid) {
  168. return dcache($this->sessid,self::prefix);
  169. }
  170. public function onGc($expire) {
  171. return true;
  172. }
  173. public function set_cookie($sid)
  174. {
  175. $expire_time = time() + self::expire_min() * 60;
  176. if(is_localdebug()) {
  177. fcgi_setcookie("MPHPSESSID","{$sid}",$expire_time,'/',LOCAL_DOMAIN);
  178. } else {
  179. fcgi_setcookie("MPHPSESSID","{$sid}",$expire_time,'/','.lrlz.com');
  180. }
  181. }
  182. private static function expire_min()
  183. {
  184. if(is_debug()) {
  185. return 43200;
  186. } else {
  187. return 43200;
  188. }
  189. }
  190. static public function read_other_session($sid)
  191. {
  192. $data = rcache($sid,self::prefix);
  193. $org = $_SESSION;
  194. $_SESSION = [];
  195. if(session_decode($data[self::session_name]) == true) {
  196. $data = $_SESSION;
  197. $_SESSION = $org;
  198. return $data;
  199. } else {
  200. $_SESSION = $org;
  201. return false;
  202. }
  203. }
  204. static public function write_other_session($sid,$data)
  205. {
  206. $org = $_SESSION;
  207. $_SESSION = $data;
  208. $data = session_encode();
  209. wcache($sid,array(self::session_name => $data),self::prefix,self::expire_min());
  210. $_SESSION = $org;
  211. }
  212. }