ini中关于session的配置一般为
1 2
| session.save_handler = "files" session.save_path = "/tmp/session"
|
session默认以文件的形式保存在服务器。用session.save_path来设置保存session文件的路径.
也可以在php代码中通过session_save_path()函数来获取或设置保存路径。 如:
1
| session_save_path("/tmp/session");
|
也可以通过ini_set设置session的相关配置。 如:
1
| ini_set('session.save_path','/tmp/session');
|
现在由于多服务器部署,以文件保存的session只能各自保存在各个前端服务器上,无法共享。 因此现在一般将session保存到memcache、redis、数据库等可共享的服务中。
ini中设置保存方式
如保存在redis中时
1 2 3 4
| session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379" session.save_path = "tcp://127.0.0.1:6379?user=password" #有密码的redis #保存在redis中的key为 "PHPREDIS_SESSION:".session_id();
|
如保存在memcache中时:
1 2 3
| session.save_handler = memcache session.save_path = "tcp://127.0.0.1:11211" #保存在memcache中的key为session_id()
|
在php.ini中的配置也可通过ini_set函数来设置。 这种通过ini配置的方法操作简单,适合小规模项目使用。
使用 session_set_save_handler
session的相关操作有 开启,关闭,读操作,写操作,销毁,过期回收 可以将这些操作写成自定义函数或类的方法,然后通过 session_set_save_handler 设置session的操作由自定义的函数来实现即可。 如:在数据库中保存session
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| class DBSession{ private $_c; public function open($savePath, $saveName){ $this->_c = mysql_connect('127.0.0.1', 'root', 'root'); mysql_select_db('test'); return true; } public function close(){ mysql_close(); return true; } public function write($sessionId, $data){ $sql = "insert into session(`sessionId`, `data`, `createTime`) values ('{$sessionId}','{$data}','".time()."')"; mysql_query($sql); return true; } public function read($sessionId){ if($res = mysql_query("select data from session where sessionId='{$sessionId}'")){ if($row = mysql_fetch_row($result)) return $row['data']; } return ''; } public function destroy($sessionId){ mysql_query("delete * from session where sessionId='{$sessionId}'"); return true; } public function gc($maxLifeTime){ $toDelete = time()-$maxLifeTime; mysql_query("delete from session where createTime<'{$toDelete}'"); return true; } } $sessionHandler = new DBSession; session_set_save_handler( [$sessionHandler, 'open'], [$sessionHandler, 'close'], [$sessionHandler, 'read'], [$sessionHandler, 'write'], [$sessionHandler, 'destroy'], [$sessionHandler, 'gc'] );
|
php5.4以上可自己写类继承SessionHandlerInterface,实现该接口定义的方法。
1 2 3 4 5 6 7 8 9
| class DBSession implements SessionHandlerInterface{ public function open(){} public function close(){} public function read(){} public function write(){} public function gc(){} public function destroy(){} } session_set_save_handler(new DBSession, true);
|
总结:
更推荐使用 session_set_save_handler 来控制session保存,原因如下:
- 直观明了。如果在ini中配置,可能只有运维或有一定权限的人才能看到。
- 修改方便,如果在ini中配置,一旦修改则需要重启php-fpm或Apache。修改代码一般只需一次部署即可。
- 学习成本低,一次学习,多重使用方式。在ini中配置mysql、memcache、redis各不同,可能还需要去了解各种保存方式使用的key。 开发以实现需求为目的,不断学习也是为了实现需求。但应该尽可能避免不必要的学习。毕竟时间有限。
- 使用灵活。在多服务器、一致性hash、memcache加密等方面,设置灵活。