打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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 squeeze14sessionSession Support     enabledRegistered save handlers    files user sqliteRegistered serializer handlers  php php_binary wddxDirective   Local Value Master Valuesession.auto_start  Off Offsession.bug_compat_42   Off Offsession.bug_compat_warn Off Offsession.cache_expire    180 180session.cache_limiter   none    nocachesession.cookie_domain   no value    no valuesession.cookie_httponly Off Offsession.cookie_lifetime 0   0session.cookie_path /   /session.cookie_secure   Off Offsession.entropy_file    no value    no valuesession.entropy_length  0   0session.gc_divisor  1000    1000session.gc_maxlifetime  2700    1440session.gc_probability  0   0session.hash_bits_per_character 5   5session.hash_function   0   0session.name    a6252c638b628a21b4b4b1cf3338a103    PHPSESSIDsession.referer_check   no value    no valuesession.save_handler    user    filessession.save_path   /var/lib/php5   /var/lib/php5session.serialize_handler   php phpsession.use_cookies On  Onsession.use_only_cookies    On  Onsession.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 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)页面,正确保存到会话失败!

<?phpclass 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 handlersregister_shutdown_function('session_write_close');

如果我看一些Joomla会话类,我预测存储到APC,数据库和XCache将无法通过此测试,因为它们使用自定义函数而无需正确实现打开或关闭.

我对Joomla不熟练,所以你必须自己实现Joomla使用会话进入这个测试脚本的方式.

最后一点:如果数据库中的单个数据集无法锁定(例如,您正在使用MyISAM表),那么实际上您无法使用此表来存储会话数据.在桌面上获取锁定将停止所有其他USERS会话.

来源:https://www.icode9.com/content-1-267601.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
PHP漏洞函数总结
【Laravel系列7.3】Session与响应
php session存储到文件、memcache或redis
iframe自适应高度问题
php session二维数组,二维数组用法
vJoomla模板CSS解析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服