我正面临着我见过的 PHP 最奇怪的问题。我会尽量做到详尽无遗,因为每个细节都很重要。
我有 3 个 PHP 页面,它们的 HTML 是使用 Smarty 生成的。他们都session_start()
在顶峰打电话。
- 第一个页面可能很重,它显示了大量可点击的图片,这些图片是 PHP 复杂对象的预览
- 如果选择了一张图片,它将指向具有特定 URL 的第二页。此页面将生成一个与 URL 信息相关的 PHP 对象(因此此页面不需要上一页的信息即可工作。如果您将此 URL 复制粘贴到任何时候它都会起作用)。这个对象将被存储到
$_SESSION
一个唯一的 id 中。 - 第三页作为 img src 包含在第二页的 HTML 代码中(使用 Smarty 生成)。这是一个 PHP 页面,在 URL 参数中具有对象的会话 ID,并在 $_SESSION 中读取对象的信息,创建它的图像预览并变成带有标题('Content-type: image/jpeg')的图像。
总结一下:沉重的第一页 => 第二页创建 PHP 对象并将其存储到$_SESSION
=> 第三页,包含在第二页的 HTML 代码中,搜索该对象并创建预览。
问题是,有时,这第三页试图加载对象,$_SESSION
但它不存在!
一些事实:
- 当第二个页面作为具有自己的 URL 的独立页面加载时,该问题永远不会发生
- 该问题仅在沉重的第一页开始加载图像时随机发生,我们疯狂地单击第一个出现的图像
- 无论情况如何,如果我
$_SESSION
在第二页的最后转储变量,我总是可以在会话中看到生成的对象
所以看起来问题位于第二页的最后和第三页的开头之间,但这一切都与第一页的活动有关!我所知道的是它与页面之间的快速导航相关联。
我几乎尝试了一切:
session_write_close()
任何可能的地方(在 smarty 显示之前/之后的页面末尾,然后在之前的开头session_start()
)exit()
在我的脚本末尾添加- 即使
sleep(1)
在第三个开始时,以防会话关闭操作需要更多时间
没有任何效果。我没有更多的线索......也许Smarty?也许一些奇怪的 PHP 会话行为名为 bug #4454 某处?
非常感谢您在此帮助我。
serialize()
编辑:聊天后的一段代码
/* ===== Page2.php ===== */ /*创建对象$card并设置一些值...*/ /*调用提供卡片预览的函数*/ $assigns['front'] = $card->getPreviewURL(); /*其他东西...将$assigns分配给smarty ...等*/ /* ===== 卡片对象类 ===== */ 函数 getPreviewURL() { $_SESSION['products'][$this->getObjectId()] = serialize($this); $url = '/page3.php?s='.$this->getObjectId(); 返回 $url; } /* ===== Page2.html ===== */ img src="{$front}" alt="toto" /* ===== Page3.php ===== */ /*获取id值并读取会话*/ if(!empty($_GET['s'])) { session_write_close(); $session = 新会话; if(!empty($_SESSION['products'][$_GET['s']])) { $product = unserialize($_SESSION['products'][$_GET['s']]); } 别的 { log('$_SESSION[products]['.$_GET['s'].'] 不存在'); header("状态:404 未找到"); 出口; } }
当发生错误时,我得到:
page2.php 调试日志: 会话值:[o20aee110e0853e74da4d17c9b7ab3075]=>O:8:"Postcard":19:{s:4:"tmpl";O:16:"PostcardTemplate":20:{s:2:"id";s:3: "152";s:2:"or";i:0;s:3:"ord";s:2:"14";s:11:"description";s:0:"" ... 等等
page3.php 调试日志: $_SESSION[产品][o20aee110e0853e74da4d17c9b7ab3075] 不存在