1

我正面临着我见过的 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] 不存在
4

1 回答 1

1

问题可能在于,PHP 尝试反序列化您的对象但找不到类定义。

您可以执行以下两项操作之一:

在将对象放入会话之前手动序列化()对象,并在加载类定义后对其进行反序列化() 。

或者:使用自动加载

于 2011-06-22T16:09:26.603 回答