为何精简版PHP include代码始终返回空值?原代码却正常运行
问题根源:PHP运算符优先级搞的鬼!
首先明确:短三元运算符(准确说是三元条件运算符?:)绝对不是只能在echo里用,你的精简版代码出问题,核心原因是没注意PHP的运算符优先级,导致代码执行顺序完全偏离了你的预期。
先看原版代码的逻辑
原版代码的执行流程很清晰:
if($pages){ include('public/pages/'.$pages->page.'.php'); }else{ include('public/pages/errors/404.php'); }
- 先判断
$pages是否为“真”(比如是否存在、非空) - 如果为真,拼接路径
public/pages/[页面名].php并包含 - 如果为假,直接包含
public/pages/errors/404.php
再拆解你的精简版代码为什么错
你写的精简版代码是:
include('public/pages/' . ($pages) ? $pages->page : "errors/404" . '.php');
PHP里,字符串连接符.的优先级比三元运算符?:高,所以这段代码的实际执行顺序是这样的:
- 先执行
'public/pages/' . ($pages):如果$pages不存在,这会变成'public/pages/'(因为null/空值转成字符串就是空) - 然后执行
include('public/pages/'):包含一个目录会返回false(PHP不允许直接包含目录) - 接着判断这个include的返回值(false),因为条件为假,所以执行
"errors/404" . '.php'得到"errors/404.php" - 但问题是,整个表达式的逻辑变成了
(include(...)) ? ... : ...,而不是你想要的include( ... ? ... : ... )!
也就是说,你根本没有把三元运算的结果用来拼接路径,反而先错误地include了一个目录,然后三元运算的结果根本没被作为include的参数,自然会返回空(甚至可能报错)。
正确的精简写法
要让三元运算先执行,再参与字符串拼接,只需要给整个三元表达式加一层括号:
include('public/pages/' . ($pages ? $pages->page : 'errors/404') . '.php');
这样执行顺序就对了:
- 先判断
$pages是否为真,得到$pages->page或者'errors/404' - 再把这个结果和前后的字符串拼接成完整路径
- 最后执行include这个正确的路径
补充:短三元运算符的正确使用
短三元运算符(比如$var ?: 'default',是$var ? $var : 'default'的简写)可以在任何需要条件判断赋值/拼接的场景用,只要注意运算符优先级——当它和其他运算符(比如.、+等)混合使用时,一定要用括号明确执行顺序,避免逻辑错乱。
内容的提问来源于stack exchange,提问作者user8517929
相关产品推荐
相关产品推荐

