PHP PDO执行含UNION子查询的出场统计SQL返回多余换行及转义异常
异常根因定位
你观察到的两类异常,和SQL里写嵌套子查询没有关联,是代码流程和环境配置的疏漏叠加导致的:
关于字段值带\n的误解
你看到print_r输出里满屏的\n,是print_r函数自身排版输出的转义字符,不是数据库返回的字段值尾部被追加了换行。
仔细对照你贴的print_r内容:所有实际字段值(比如[player] => 0、[game] => 53)后面都没有附加换行,\n全是print_r打印对象结构时,用来标记自身排版换行的转义序列——之前没遇到这类观感问题,只是因为之前的代码没有把print_r的格式化输出混到接口响应里。
关于前端收到多余反斜杠转义的来源
这类[{\"player\":\"0\"...}]格式的带反斜杠JSON,是多层转义叠加的结果:
- 代码里在执行SQL前提前调用了
$stmt->fetchColumn(),会提前从结果集游标里读走第一行数据,打乱后续结果读取的顺序 - 接口输出时没有做响应隔离:调试用的print_r输出、PHP输出缓冲区里的残留内容被一起混进了返回值
- PHP环境里遗留了自动字符串转义的逻辑(旧版本的魔术引号配置),把原本不需要转义的双引号额外加了一层反斜杠;后续返回过程中又被整体做了一次addslashes,就形成了你看到的满屏
\"的效果。
对应解决步骤
- 删掉代码里多余的
$count = $stmt->fetchColumn();。这行代码没有任何业务作用,会破坏PDO结果集的读取流程 - 清理输出缓冲、规范接口返回流程:在准备输出响应前调用
ob_clean()清空所有调试产生的输出,设置正确的JSON响应头,直接编码输出最终数据后终止脚本:// 数据库查询逻辑完成、组装好$data数组后 header('Content-Type: application/json; charset=utf-8'); ob_clean(); echo json_encode($data, JSON_UNESCAPED_UNICODE); exit; - 修正SQL里的非规范写法:当前SQL的SELECT子句包含
game字段,但GROUP BY仅按player聚合,在开启严格SQL模式的数据库中会直接报错,且聚合后取任意一行的game值没有业务意义,直接删掉该字段;同时对齐UNION两个分支的字段别名,避免字段名不匹配的报错。修正后的核心SQL结构为:select player, count(*) AS totalApps, sum(first) AS starter, sum(second) AS subbedOnFor from ( select game, player, 1 as first, 0 as second from appearances union all select game, subbedOnFor as player, 0 as first, 1 as second from appearances ) myApps JOIN players ON myApps.player = players.playerid JOIN games ON myApps.game = games.gameid WHERE games.date >= :start AND games.date <= :end group by player ORDER BY totalApps DESC LIMIT :limit - 处理环境层面的自动转义:检查php配置中的
magic_quotes_gpc、magic_quotes_runtime项,全部设置为Off,避免数据库返回的字符串被自动添加反斜杠。如果无法修改php配置,可以在返回前遍历$data数组,用stripslashes()移除多余的转义符。
内容的提问来源于stack exchange,提问作者Dan Crookes
相关产品推荐
相关产品推荐

