如果我将感叹号放入变量名中,PHP 的行为会很奇怪
Posted
技术标签:
【中文标题】如果我将感叹号放入变量名中,PHP 的行为会很奇怪【英文标题】:Weird PHP behavior if I put exclamation point into variable name 【发布时间】: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)
【参考方案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”。管道仍然被禁止。
修复:
-
将 php.ini 中的 session.serialize_handler 更改为 php_binary 或 php_serialize
重启网络服务器。
玩得开心!
【讨论】:
以上是关于如果我将感叹号放入变量名中,PHP 的行为会很奇怪的主要内容,如果未能解决你的问题,请参考以下文章