来自C#我必须用PHP做一个项目。
我正在使用此代码:
$transport = 'T';
$vehicle = (
( $transport == 'B' ) ? 'bus' :
( $transport == 'A' ) ? 'airplane' :
( $transport == 'T' ) ? 'train' :
( $transport == 'C' ) ? 'car' :
( $transport == 'H' ) ? 'horse' :
'feet' );
echo $vehicle;
我希望它能打印train
,但我得到horse
。键盘示例:http://codepad.org/rWllfrht
谁能解释这种奇怪的行为?
答案 0 :(得分:16)
在其他答案中没有看到关于为什么你的代码被破坏的任何解释,所以这是一个快速的破败。
这里的问题更明显的是你添加括号以使隐含的评估顺序更明确。
这是您的代码的精简版本,仍会产生错误的“马”结果:
$t = 'T';
( $t == 'T' ) ? 'train' :
( $t == 'C' ) ? 'car' :
( $t == 'H' ) ? 'horse' : 'feet';
首先,让我们展开它:
( $t == 'T' ) ? 'train' : ( $t == 'C' ) ? 'car' : ( $t == 'H' ) ? 'horse' : 'feet';
接下来,我将添加明确的括号,其中已经有隐含的括号:
((($t == 'T') ? 'train' : ($t == 'C')) ? 'car' : ($t == 'H')) ? 'horse' : 'feet';
接下来,我们可以解决您的比较:
((true ? 'train' : false) ? 'car' : false) ? 'horse' : 'feet';
你应该开始看为什么这个坏了。第一个三元评估true ? 'train' : 'false'
到'train'
:
('train' ? 'car' : false) ? 'horse' : 'feet';
因为当转换为布尔值时'train'
为真,结果现在为'car'
:
'car' ? 'horse' : 'feet';
同样,因为非空字符串是“true”,结果现在是“马”。因此,第一次true
出现在你可怕的嵌套case语句中时,结果将级联所有剩余的语句,抛出下一个运算符的“true”分支的前一个值。
解决方案是避免使用此代码。这是一个远远过于聪明的尝试,结果是一个破碎,难以理解的混乱。绝对没有理由使用它。选择一个switch
语句,它是专门构建的,用于您正在尝试的内容。
答案 1 :(得分:3)
由于PHP语言语法中的错误,这不能按预期工作,如:http://en.wikipedia.org/wiki/%3F:#PHP
这是一个可以工作的简单版本:
$transport = 'T';
$vehicle = (
( $transport == 'B' ? 'bus' :
( $transport == 'A' ? 'airplane' :
( $transport == 'T' ? 'train' :
( $transport == 'C' ? 'car' :
( $transport == 'H' ? 'horse' :
'feet' ))))));
echo $vehicle;
但正如其他人所说,我同意这不是最好的方法。您可以使用switch case,if else if或associative array,并且更具可读性。
答案 2 :(得分:1)
这是PHP的一种“按预期工作 - 甚至是明显错误”的行为。它不会以这种方式关联,因此虽然此代码适用于大多数其他语言,但它将在PHP中失败。课?学会在不寻常的关联范式中使用括号。第二课?三元不是一个神奇的子弹,虽然它可以很好和紧凑,它应该只在它可读时使用。恕我直言的嵌套三元语句很难看。
答案 3 :(得分:0)
我不确定为什么你选择使用这种语法形式,正如comment中提到的那样,这将是一个调试的噩梦......一个切换案例可能是一个更好的选择 - < / p>
$vehicle = '';
switch($transport){
case 'B' :
$vehicle = 'bus';
break;
case 'A' :
$vehicle = 'airplane';
break;
...
default:
// undefined cases
break;
}
参考文献 -
答案 4 :(得分:0)
如果你想做这样的事情,请学习爱情的禁忌:
$vehicle = ( ( $transport == 'B' ) ? 'bus' :
(( $transport == 'A' ) ? 'airplane' :
(( $transport == 'T' ) ? 'train' :
(( $transport == 'C' ) ? 'car' :
(( $transport == 'H' ) ? 'horse' :'feet')))) );
由于PHP的三元http://php.net/manual/en/language.operators.comparison.php操作顺序,需要明确包含三元组的每个右侧。
顺便说一句,从那个页面他们明确建议不要像这样堆叠它们......
注意:建议您避免“堆叠”三元表达式。 PHP在单个语句中使用多个三元运算符时的行为是不明显的:
答案 5 :(得分:-1)
我不会建议您使用此类代码,但出于教育目的,它应该是
$transport = 'T';
$vehicle = (
($transport == 'B') ? 'bus' :
(($transport == 'A') ? 'airplane' :
(($transport == 'T') ? 'train' :
(($transport == 'C') ? 'car' :
(($transport == 'H') ? 'horse' : 'feet'))))
);
echo $vehicle;
更好的代码应该是
$transport = 'T';
switch ($transport) {
case 'A' :
$vehicle = 'airplane';
break;
case 'B' :
$vehicle = 'bus';
break;
case 'C' :
$vehicle = 'car';
break;
case 'H' :
$vehicle = 'horse';
break;
case 'T' :
$vehicle = 'train';
break;
default :
$vehicle = 'teleportation';
break;
}
echo $vehicle;
或者更好的是:
$transport = 'T';
$array = array('A'=>'airplane','B'=>"bus","C"=>"car","H"=>"horse","T"=>"train");
echo isset($array[$transport]) ? $array[$transport] : null;
或者,使用数据库:
SELECT name FROM transpotationTable WHERE someKey = '$transport'