【问题标题】:Weird PHP behavior if I put exclamation point into variable name如果我将感叹号放入变量名中,PHP 的行为会很奇怪
【发布时间】:2011-03-30 01:17:58
【问题描述】:

PHP 本身有我见过的最奇怪的问题。

设置:

IIS 下的 PHP 5.33(也试过 PHP 5.2.14)

问题: 一旦我将感叹号放入会话数组中的键中,PHP 就会删除所有会话数据。

示例:

session1.php

session_start();
$_SESSION["foo"] = 'test';
header('Location: session2.php');

session2.php

session_start();
var_dump($_SESSION);
die();

工作正常,我看到打印出可变数据。

array(1) { ["foo"]=>  &string(4) "test" } 

但是如果我将第一个文件中的行更改为

$_SESSION["foo!"] = 'test'; 

$_SESSION["f!oo"] = 'test'; 

我的意思是如果我添加感叹号 - 那么当我到达第二个文件时 $_SESSION 数组是空的

array(0) { } 

当我在 5.2.14 上时,我认为这是一个错误的 PHP 版本,但升级没有帮助。 我什至不知道问题可能是什么。也许这与 Windows 设置或 IIS 有关?

有什么想法吗?

【问题讨论】:

  • 您使用的是什么会话后端?普通文件? session.save_handler=files
  • 我的 php 5.3.1 与 "!" 配合得很好(xampp)。
  • 有一个旧的错误报告,但显然它无法重现 (bugs.php.net/bug.php?id=14160)

标签: php iis session variables


【解决方案1】:

那么你的问题是什么?这个错误的原因是什么或如何避免它?
第一个可能是因为一些奇怪的 PHP 内部结构。例如,您不能使用具有相同结果的数字键。
后一个更简单 - 不要将感叹号放入会话数组中的键中。

我记得,PHP 会话机制来自 PHPLib - 有史以来第一个 PHP 框架。由一些志愿学生撰写。不是一个非常理想的。一旦在 4.0 版本中添加到 PHP 中,只能在 4.1 版本中使用,但仍然有一些奇怪的遗留问题,比如 register_globals 支持。后一个很可能是您的问题的原因。 $_SESSION 数组键必须是有效的 PHP 变量名,以实现古老的 register_globals 行为,即会话变量成为全局 PHP 变量。

【讨论】:

  • register_globals 在 5.3 中已被弃用。 cbglum 使用的是 5.3.3
  • 在注意到问题后,我首先关闭了 register_globals。现在我更加确信这更多的是 IIS 或 Win 问题,但我不知道如何在不离开此服务器的情况下解决此问题。有什么提示吗?
  • @cbglum 如果我猜对了,这不是 setting 问题,而是 PHP 核心代码问题。通过更改设置,您不会更改代码本身,它保持不变。所有的错误都完好无损。我已经告诉过你一个提示:不要使用!在密钥名称中标记。至少再深一层,$_SESSION["cart"]["f!oo"] = 'test';,但我还是不明白你为什么坚持用这个奇怪的名字
【解决方案2】:

不是 Windows,它不是 Apache 或任何其他网络服务器,它是 PHP 核心。

我看了一下 - 从 5.3 到 5.6,问题仍然存在:你不能有一个“!” (感叹号)或“|” (管道)在会话密钥中。

Suhosin 补丁将部分修复它。然后,您可以在钥匙内的任何位置有一个感叹号,但不能在第一个位置,所以“foo!”是允许的,但不是“!foo”。管道仍然被禁止。

修复:

  1. 将 php.ini 中的 session.serialize_handler 更改为 php_binaryphp_serialize
  2. 重启网络服务器。

玩得开心!

【讨论】:

    猜你喜欢
    • 2015-01-30
    • 2015-03-09
    • 2013-06-22
    • 2021-10-28
    • 1970-01-01
    • 2014-03-16
    • 2015-04-01
    • 2019-09-16
    • 2022-08-24
    相关资源
    最近更新 更多