首先,如果相关,则在会话处理程序中。此函数是写入数据库的函数,并与我的其他函数一起传递给session_set_save_handler
session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc');
我有这段代码......
$qid = "select count(*) as total
from zen_sessions
where sesskey = '" . $key . "'";
if(!class_exists('DB'))
require_once dirname(dirname(__FILE__)).'/class/DB.class.php';
var_dump(new DB()); //this is line 109
$total = DB::select_one($qid);
条件和var_dump
用于测试。奇怪的是,有时候它可以正常工作,而有些则给我一个错误:
Fatal error: Class 'DB' not found in /path/to/file/session_functions.php on line 109
我无法想象这有什么不会在需求而不是var_dump
崩溃,为什么只有时呢?
提前感谢任何见解。
编辑 - 回复评论/问题:
以下代码的结果
var_dump(class_exists('DB', false));
var_dump(is_file(dirname(__DIR__).'/class/DB.class.php'));
是:
bool(false) bool(true)
在尝试要求之前和在require之后的相同结果之前(或者当它没有给我一个错误时为true) 看起来像:
bool(true) bool(true) object(DB)#3 (0) { }
以前的代码块是每5页加载一次的结果,而错误是其他4的结果。
Edit2 - 新发现。
更奇怪的是根据manual我永远不会看到这些调试语句或错误
注意:
"写"在输出流之后才执行handler 关闭。因此,来自" write"中的调试语句的输出。处理器 将永远不会在浏览器中看到。如果需要调试输出, 建议将调试输出写入文件。
编辑3 - 为清晰起见的注释:
DB
类应该已经自动加载(并且在应用程序的其他任何位置)class_exists
和require仅用于测试目的。
编辑4 - 堆栈跟踪
我决定尝试在没有找到类来查看堆栈跟踪时抛出异常,这就是我得到的
Fatal error: Uncaught exception 'Exception' with message 'DB Class Not Found.'
in /path/to/file/session_functions.php:108
Stack trace: #0 [internal function]: sess_write('074dabb967260e9...', 'securityToken|s...')
#1 {main} thrown in /path/to/file/session_functions.php on line 108
答案 0 :(得分:1)
我唯一可以想到可能造成这种情况的事情,来自于session_set_save_handler的PHP文档中的通知:
警告
如果在脚本终止中关闭会话,则会使用某些SAPI更改当前工作目录。可以使用session_write_close()关闭会话。
根据您的体验,我猜测当前的工作目录已更改,因此require_once
找不到该文件。
我会尝试将session_write_close();
添加到您的函数中的某个位置,看看是否可以修复它。
不可否认,不确定为什么is_file
在这种情况下会返回true,但也许值得一试。
答案 1 :(得分:1)
即使我不能确定,但我敢打赌,错误在其他地方,并且它只是按照你所描述的那样投射出来。
为了测试和调试代码,您需要使用PDT之类的调试器。但问题是你需要调试一部分超出调试器范围的代码,即会话编写者!要解决此问题,您可以使用session_write_close。你可以把它放在引导程序的末尾,如果你没有引导程序,你可以这样做:
<?php
function shutdown_function()
{
session_write_close();
}
register_shutdown_function('shutdown_function');
然后通过设置断点,您可以从此处开始调试会话代码。如果我赢了赌注,请告诉我。
答案 2 :(得分:0)
尝试:
$save_handler = new DB();
session_set_save_handler($save_handler, true);
然后在你的类中映射read,write等函数。我遇到了一个类似的问题(关于一个没有找到的类的奇怪的随机错误)用redis实现HHVM的另一个用户的自定义保存处理程序解决方法,这就是我修复它的方法。如果您正在使用HipHopVirtualMachine(或者可能是其他类型的JIT编译器或应用程序缓存),有时您的项目可以缓存某些函数而不进行更新,从而产生这样的奇怪错误。通常重启fastcgi守护进程并为你的一个文件添加空格足以迫使它重新解释你的项目。