看到yii2.0源码中大量使用
/** * PHP getter magic method. * This method is overridden so that attributes and related objects can be accessed like properties. * * @param string $name property name * @throws \yii\base\InvalidParamException if relation name is wrong * @return mixed property value * @see getAttribute() */ public function __get($name) { if (isset($this->_attributes[$name]) || array_key_exists($name, $this->_attributes)) { return $this->_attributes[$name]; } elseif ($this->hasAttribute($name)) { return null; } else { if (isset($this->_related[$name]) || array_key_exists($name, $this->_related)) { return $this->_related[$name]; } $value = parent::__get($name); if ($value instanceof ActiveQueryInterface) { return $this->_related[$name] = $value->findFor($name, $this); } else { return $value; } } }
其中:
isset($this->_attributes[$name]) || array_key_exists($name, $this->_attributes)
这类判断比较多,百思不得其解,翻看官网才得知,
isset()主要判断是否为null,例如 $arr = ['a'=>1, 'b'=>null] ,isset($arr['a']返回true, isset($arr['b'])返回false,
而array_key_exists主要判断键值是否存在,array_key_exists('a', $arr)返回true, array_key_exists('b', $arr)也返回true;
关键是yii2的作者为啥要做两次判断,这次是我疑惑的重点。
个人认为还是出于性能考虑,因为isset效率高于array_key_exists,但同时为保证语句确实是为了到达array_key_exists的作用,
提前做了一次isset()判断,借助比较判断的短路效应,如果isset()为真则说明数组中key必然存在,减少array_key_exists的低效判断,
而isset()为假不一定说明key不存在,有可能是key存在但值是null,所以在用array_key_exists做一次检测,达到效率与效果的平衡。