【问题标题】:PHP/Smarty - Random Session data loss between 2 pagesPHP/Smarty - 两页之间的随机会话数据丢失
【发布时间】:2011-06-22 16:05:10
【问题描述】:

我遇到了我见过的 PHP 最奇怪的问题。我会尽量做到详尽无遗,因为每个细节都很重要。

我有 3 个 PHP 页面,它们的 HTML 是使用 Smarty 生成的。他们都在顶部调用session_start()

  • 首页可能会很重,会显示大量可点击的图片,这些图片是 PHP 复杂对象的预览
  • 如果选择了一张图片,它会引导到具有特定 URL 的第二页。此页面将生成与 URL 信息相关的 PHP 对象(因此此页面不需要上一页的信息即可工作。如果您复制粘贴这个 URL 在任何时候都可以使用)。此对象将存储到具有唯一 ID 的 $_SESSION
  • 第三页作为 img src 包含在第二页的 HTML 代码中(使用 Smarty 生成)。这是一个 PHP 页面,在 URL 参数中具有对象的会话 id,并在 $_SESSION 中读取对象的信息,创建它的图像预览并转换为带有 h​​eader('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 ...等*/ /* ===== 卡片对象 class===== */ 函数 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] 不存在

【问题讨论】:

  • 确保 error_reportingE_ALL 并在第 2 页和第 3 页上查找通知/错误/警告。我会在一个选项卡中打开第 2 页,在另一个选项卡中打开第 3 页,然后继续尝试。不要在第 3 页显示图像,而是转储 $_SESSION 数据。

标签: php session smarty loss


【解决方案1】:

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

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

serialize() 在将对象放入会话之前手动将其放入会话中,在加载类定义后将其unserialize()

或者:使用autoloading

【讨论】:

  • 这正是 PHP 会话所做的,所以真的没有意义。
  • @Rudie:是的,因为它是自动执行的,所以在加载类定义之前它会被反序列化。
  • 这很有道理...有点... PHP必须比这更聪明!为什么有时会起作用?
  • @Rudie:这是个好问题。一旦第一次访问,PHP 可能会反序列化数据,我不知道实现细节。我会尝试重现它。
  • 应该很容易找到:Array ( [test] => __PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] => Oele ) )
猜你喜欢
  • 2019-04-04
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多