PHP7中的isset-PHP7

资源魔 39 0
晋级 php7 后 isset 没有太对了

公司晋级 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开发自学

抱歉,评论功能暂时关闭!