PHP数字索引数组赋值代码Apache正常Ajax调用异常是什么原因?
问题根源
你遇到的问题核心是PHP字符串变量的偏移赋值特性,结合变量提前被覆盖导致的,具体原因如下:
- PHP中如果对字符串类型的变量使用数组方括号语法赋值,会被识别为给字符串指定偏移位置写入字符,且只会保留赋值内容的第一个字符,示例如下:
$val = 'test'; // 字符串类型 $val[0] = 'well'; echo $val; // 输出 `west`,只会取`well`的第一个字符`w`替换偏移0的位置
- 你的Ajax调用脚本中,在执行
$val = array();初始化数组之前,$val变量已经被赋值为字符串类型:- 大概率是你的Ajax脚本环境开启了已经废弃的
register_globals配置,或者代码中存在extract($_GET)/extract($_POST)这类自动提取请求参数的逻辑,刚好Ajax请求中携带了名为val的参数,导致$val被提前赋值为字符串。 - 小概率是你写代码时手误把
$val = array();写成了$val == array();,变成条件判断没有执行赋值操作,$val还是之前的字符串类型。
- 大概率是你的Ajax脚本环境开启了已经废弃的
- 普通网页运行正常是因为对应页面里没有提前给
$val赋值为字符串的操作,$val被正确初始化为数组,赋值逻辑正常。 - 你修改为字母索引后运行正常,是因为修改代码时你重新写了正确的
$val = array();初始化逻辑,$val被正确识别为数组,赋值不再触发字符串偏移特性。
修复方案
- 排查Ajax脚本初始化
$val之前的代码,删除提前给$val赋值的逻辑,或者修改变量名避免冲突。 - 关闭
register_globals配置(PHP 5.3之后已默认关闭,该配置存在严重安全风险),避免请求参数自动注册为全局变量。 - 字符串拼接时避免有歧义的双引号内嵌数组写法,推荐直接拼接变量或者用大括号包裹数组表达式消除解析歧义:
// 推荐写法1:直接拼接 $q_search .= $val[$key]; // 推荐写法2:大括号包裹消除解析歧义 $q_search .= "{$val[$key]}";
- 另外你贴出的示例代码存在引号未闭合、双引号嵌套的语法错误,也请同步修正。
内容的提问来源于stack exchange,提问作者Dave_K
相关产品推荐
相关产品推荐

