php随机丢失部分会话
我正在为Joomla开发! 2.5.6和此代码用于与Joomla 1.5一起正常工作
第1页 JFactory::getSession()->clear('domain_name','dominiForm'); 第2页 $session = JFactory::getSession(); $session->set('domain_name',$domain_name,'dominiForm'); 第3页 $session = JFactory::getSession(); $domain_name = $session->get('domain_name',null,'dominiForm'); 问题是第3页有时返回null,有时它返回保存的值.它在我的开发机器上运行正常,但在生产服务器上没有,我不知道该怎么做. 这是服务器上的一些phpinfo() PHP Version 5.3.3-7+squeeze14 session Session Support enabled Registered save handlers files user sqlite Registered serializer handlers php php_binary wddx Directive Local Value Master Value session.auto_start Off Off session.bug_compat_42 Off Off session.bug_compat_warn Off Off session.cache_expire 180 180 session.cache_limiter none nocache session.cookie_domain no value no value session.cookie_httponly Off Off session.cookie_lifetime 0 0 session.cookie_path / / session.cookie_secure Off Off session.entropy_file no value no value session.entropy_length 0 0 session.gc_divisor 1000 1000 session.gc_maxlifetime 2700 1440 session.gc_probability 0 0 session.hash_bits_per_character 5 5 session.hash_function 0 0 session.name a6252c638b628a21b4b4b1cf3338a103 PHPSESSID session.referer_check no value no value session.save_handler user files session.save_path /var/lib/php5 /var/lib/php5 session.serialize_handler php php session.use_cookies On On session.use_only_cookies On On session.use_trans_sid 0 0 解决方法
您正在生产服务器上使用自定义session.save_handler.可能你没有在你的开发机器上.
请注意,Joomla确实让会话锁定错误 – 没有.基本上这意味着你是竞争条件的受害者. 如果你看一下the documentaion for session_set_save_handler(),你会发现有回调,包括open,close,read,write,destroy和gc(垃圾回收). open应该“初始化”东西,但最重要的是应该获取用于存储的资源的写锁定. 读取做通常的阅读,写做写作. close应该释放写锁. 如果会话保存处理程序未获取锁定,则具有相同会话ID的多个并行请求可以相互覆盖! 您应该在服务器上执行一个简单的测试,看看是否有这个问题: <?php // initialize alternate session save handler here. //include_once "session-handler.php"; if (isset($_GET['subrequest'])) { $starttime = time(); $subrequest = intval($_GET['subrequest']); session_start(); // should wait until lock is released echo "<html><pre>"; echo "Request started on ". date("Y-m-d H:i:s",$starttime)."n"; echo "Session locked for this request on ". date("Y-m-d H:i:s"). "n"; echo "Executing subrequest ". $subrequest."n"; $_SESSION["subrequest"][] = 'collected subrequest #'.$subrequest; echo "All subrequests collected:n"; var_dump($_SESSION["subrequest"]); echo "nWaiting 1 secondn"; sleep(1); echo "Releasing session lock on ". date("Y-m-d H:i:s"). "n"; echo "</pre></html>"; exit(); } session_start(); $_SESSION['subrequest'] = array('master request'); ?> <html> <iframe src="?subrequest=1" width="90%" height="100"></iframe> <hr> <iframe src="?subrequest=2" width="90%" height="100"></iframe> <hr> <iframe src="?subrequest=3" width="90%" height="100"></iframe> </html> 这个PHP文件将初始化会话并在屏幕上发出三个iframe,几乎立即再次向服务器发出三个请求. 如果会话被探测锁定,那么每个iframe将在接下来的几秒钟内一个接一个地连续填充.另外,按照出现的顺序,$_SESSION [‘subrequest’]的控制输出应包括最后返回的子请求. 如果会话未正确锁定,则在加载主页面后,所有三个iframe将几乎立即填充,并且所有三个iframe将仅在调试输出中报告其自己的子请求以及主请求. 如果我将此实现用于文件系统存储,我得到了from the php.net documentation (Example #2)页面,正确保存到会话失败! <?php class FileSessionHandler { private $savePath; function open($savePath,$sessionName) { $this->savePath = $savePath; if (!is_dir($this->savePath)) { mkdir($this->savePath,0777); } return true; } function close() { return true; } function read($id) { return (string)@file_get_contents("$this->savePath/sess_$id"); } function write($id,$data) { return file_put_contents("$this->savePath/sess_$id",$data) === false ? false : true; } function destroy($id) { $file = "$this->savePath/sess_$id"; if (file_exists($file)) { unlink($file); } return true; } function gc($maxlifetime) { foreach (glob("$this->savePath/sess_*") as $file) { if (filemtime($file) + $maxlifetime < time() && file_exists($file)) { unlink($file); } } return true; } } $handler = new FileSessionHandler(); session_set_save_handler( array($handler,'open'),array($handler,'close'),'read'),'write'),'destroy'),'gc') ); // the following prevents unexpected effects when using objects as save handlers register_shutdown_function('session_write_close'); 如果我看一些Joomla会话类,我预测存储到APC,数据库和XCache将无法通过此测试,因为它们使用自定义函数而无需正确实现打开或关闭. 我对Joomla不熟练,所以你必须自己实现Joomla使用会话进入这个测试脚本的方式. 最后一点:如果数据库中的单个数据集无法锁定(例如,您正在使用MyISAM表),那么实际上您无法使用此表来存储会话数据.在桌面上获取锁定将停止所有其他USERS会话. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |