我正在为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
答案 0 :(得分:4)
您在生产服务器上使用自定义session.save_handler。可能你没有在你的开发机器上。
请注意Joomla确实让会话锁定错误 - 没有。基本上这意味着你是竞争条件的受害者。
如果查看the documentaion for session_set_save_handler(),您会看到有开放,关闭,读取,写入,销毁和gc(垃圾回收)的回调。
open
应该“初始化”内容,但最重要的是应该获取对用于存储的资源的写锁定。
read
,write
写作。
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 second\n";
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'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);
// the following prevents unexpected effects when using objects as save handlers
register_shutdown_function('session_write_close');
如果我看一些Joomla会话类,我预测存储到APC,数据库和XCache将无法通过此测试,因为它们使用自定义函数而没有正确实现open
或close
我对Joomla不熟练,所以你必须自己实现Joomla使用会话进入这个测试脚本的方式。
最后一点:如果数据库中的单个数据集无法锁定(例如,您正在使用MyISAM表),那么实际上您无法使用此表存储会话数据。在桌面上获取锁定将停止所有其他USERS会话。
答案 1 :(得分:0)
您是否在生产机器上使用缓存机制,如清漆?因为在处理会话和joomla时缓存总是一团糟,所以在我使用缓存时遇到了很多与缓存相关的问题(这就是为什么我目前不使用缓存,只是没有用户缓存的APC)。
答案 2 :(得分:0)
我认为你可以使用这个脚本 在第一页或第二页中使用以下脚本
$session =& JFactory::getSession();
$session->set('name', "value");
* name 是您的会话变量,值是您的值
然后在第3页使用此
$session =& JFactory::getSession();
echo $session->get('name');
* name 是您的会话变量