公司晋级 php7 后呈现了一个成绩
相似这样 isset($post->user->name) 始终为 false
以前的 php 5.6 就很失常
laravel 版本是 5.1.35(很久没晋级了)
先看看 isset
isset 用来检测变量能否设置
起首咱们来看民间的一个例子
大抵上是上面这个意义
<?php class Post { protected $attributes = ['content' => 'foobar']; public function __get($key) { if (isset($this->attributes[$key])) { return $this->attributes[$key]; } } } $post = new Post(); echo isset($post->content); // false
下面这个例子将永远前往 false,由于 foo 并非 Post 的属性,而是 __get 掏出来的
魔术办法 __isset
那末怎样处理下面阿谁成绩呢?应用魔术办法
<?PHP class Post { protected $attributes = ['content' => 'foobar']; public function __get($key) { if (isset($this->attributes[$key])) { return $this->attributes[$key]; } } public function __isset($key) { if (isset($this->attributes[$key])) { return true; } return false; } } $post = new Post(); echo isset($post->content); //true
相似 Eloquent 的例子
看着 laravel 5.1.35 的代码,咱们本人写一个简略的例子
先有一个 Model,简略的完成。__get,__set,__isset
class Model { // 寄存属性 protected $attributes = []; // 寄存关系 protected $relations = []; public function __get($key) { if( isset($this->attributes[$key]) ) { return $this->attributes[$key]; } // 找到联系关系的工具,放正在关系外面 if (method_exists($this, $key)) { $relation = $this->$method(); return $this->relations[$method] = $relation; } } public function __set($k, $v) { $this->attributes[$k] = $v; } public function __isset($key) { if (isset($this->attributes[$key]) || isset($this->relations[$key])) { return true; } return false; } }
而后咱们界说一个 Post Moel 以及一个 User Moel
class Post extends Model { protected function user() { $user = new User(); $user->name = 'user name'; return $user; } } class User extends Model { }
好了来验证一下 isset
$post = new Post(); echo 'isset 发帖用户:'; echo isset($post->user) ? 'true' : 'false'; // false echo PHP_EOL; echo 'isset 发帖用户的名字:'; echo isset($post->user->name) ? 'true' : 'false'; // false echo PHP_EOL; echo '发帖用户的名字:'; echo $post->user->name; // user name echo PHP_EOL; echo '再次判别 isset 发帖用户的名字:'; echo isset($post->user->name) ? 'true' : 'false'; // true echo PHP_EOL;
谜底
剖析下面的后果,觉得像是 php 7 isset 办法对工具的判别有了变动,假如先执行一次,$post->user->name,也就是将 user 放正在 post 的 relations 中,这样 isset ($post->user) 为 true,随后 isset ($post->user->name) 才为 true。
最初正在 Eloquent model 的 git log 中 找到了谜底,
PHP 7 has fixed a bug with __isset which affects both the
native isset and empty methods. This causes specific issues
with checking isset or empty on relations in Eloquent. In
PHP 7 checking if a property exists on an unloaded relation,
for example isset($this->relation->id) is always
returning false because unlike PHP 5.6, PHP 7 is now
checking the offset of each attribute before chaining to
the next one. In PHP 5.6 it would eager load the relation
without checking the offset. This change brings back the
intended behavior of the core Eloquent model __isset method
for PHP 7 so it works like it did in PHP 5.6.
For reference, please check the following link,
specifically Nikita Popov's co妹妹ent (core PHP dev) -
https://bugs.php.net/bug.php?id=69659
大抵上是 php7 isset 判别的时分,会顺次判别。php5.6 则会预加载关系。其实 laravel 也早正在 5 月份就做了相干的解决,以是晋级 laravel 后,天然也就不这个成绩了。
保举教程:《PHP7教程》《PHP教程》《Laravel教程》
以上就是PHP7中的isset的具体内容,更多请存眷资源魔其它相干文章!
标签: Laravel PHP7 php7开发教程 php7开发资料 php7开发自学
抱歉,评论功能暂时关闭!