情况:我们有一小段PHP代码检查变量是否具有某个值,但由于数组索引及其值尚未设置,这将创建一个E_NOTICE错误:
<?php
$arr = array();
if ($arr['name']=='john') {
echo('This should not work');
} else {
echo('In your computer, ignoring your notice');
}
这引起了很好的注意:
PHP Notice: Undefined index: name in /home/hvanmegen/test.php on line 5
PHP Stack trace:
PHP 1. {main}() /home/hvanmegen/test.php:0
现在请向我解释一下,如果该值检查会抛出错误,下面打印的代码如何正常工作而不会抛出相同的异常?!?!
<?php
$arr = array();
if (isset($arr['name']) && $arr['name']=='john') {
echo('This should not work');
} else {
echo('In your computer, ignoring your notice');
}
输出:
In your computer, ignoring your notice
当比较列表中触发第一个错误时,PHP是否只跳过第二次检查并且从未实际执行第二次检查?
此外,将两个if语句分开是否被认为是良好的编码习惯,或者我在编码方面有点过于陈旧?人们会认为检查这个的正确方法是:
<?php
$arr = array();
if (isset($arr['name'])) {
if ($arr['name']=='john') {
echo('Hi john');
} else {
echo('Hi not-john, where is john?');
}
} else {
echo('I cannot check what I do not have');
}
输出:
I cannot check what I do not have
是否只是我的强迫症想要放置&#39; isset()&#39;在另一个声明之外还是我的方法完全是多余的和过时的?或者我是否坚持你应该用尽可能多的常用语言编写代码的想法。 (使用与语言无关的语法,尽可能简单地从一种语言切换到下一种语言)?
其他编程和脚本语言(Java,C ++ / C#,Javascript,Python)如何处理这个问题?
答案 0 :(得分:9)
当比较列表中触发第一个错误时,PHP是否只跳过第二次检查并且从未实际执行第二次检查?
是。它被称为short-circuit evaluation。
&&
(和)如果左侧为假,则不评估右侧,因为结果必须为假。
||
(或)如果左侧为真,则不评估右侧,因为结果必须为真。
另外,将两个if语句分开是否被认为是良好的编码习惯,或者我在编码方面有点过于陈旧?
虽然编码风格非常个人化,但一旦理解了短路评估,就没有必要将它们分开。我相信在这种情况下,大多数程序员会将条件保持在一个if
,特别是因为它们密切相关,并且基本上是检查同一事物的两个步骤。
其他编程和脚本语言(Java,C ++ / C#,JavaScript,Python)如何处理这个问题?
与PHP相同。
答案 1 :(得分:3)
if (isset($arr['name']) && $arr['name']=='john')
肯定是&&
运算符如果第一个条件是false,编译器或解释器不会浪费时间检查其他条件,因为它没用。因此,在这种情况下,不评估第二个条件。
再次if (isset($arr['name'])) {
这个条件是假的,所以它会跳转到其他地方。
echo('I cannot check what I do not have');
答案 2 :(得分:1)
PHP isset不是一个函数。 它是一个内置的,我怀疑它有一些语言水平的魔力。这就是你在第二种情况下没有得到警告的原因。
我通常会编写一个这样的辅助函数来处理这个问题:
function check($array, $key, $expected) {
if (!isset($array[$key]) return false;
return $array[$key] == $expected;
}
PHP是否只是跳过第二次检查而从未实际执行过 每当在比较列表中触发第一个错误时进行第二次检查??
是的,PHP中的布尔运算符执行short-curcuit evaluation:子表达式从左到右进行求值,一旦解释器知道足够多,它就会返回而不对剩余的子表达式进行评估。
其他编程和脚本如何? 语言(Java,C ++ / C#,Javascript,Python)处理这个?
C ++默认处理它,构造value_type(Effectivly,返回一个新的空字符串,插入到映射的索引中。)并且有其他方法可以不经修改地访问。
Ruby返回null或构造函数中指定的默认值。
PHP有点烦人,在某些地方默默地失败,并在不期望的其他地方发出警告。
如果我不关心我写的不存在的密钥: if(check($ arr,'name',john')){ 回声('嗨约翰'); } else { 回声('我不知道你是谁。'); }
答案 3 :(得分:-2)
if ($arr['name']=='john') { ...
如果您没有带有“name”键的数组元素,则会出现错误。
isset($arr['name'])
另一方面,只检查是否有一个带有'name'键的元素。 它只是循环遍历键数组(在空数组上非常快)并返回true键存在。
结论:如果你访问一个数组元素$ arr ['name']你应该知道有这样一个元素。如果您不确定首先检查是否存在isset($ arr ['name'])
希望它有所帮助!