解决升级php7后isset方法始终为 false的问题-PHP7

资源魔 57 0
公司晋级 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 放正在 postrelations 中,这样 isset($post->user) true,随后 isset($post->user->name) 才为 true

最初正在 Eloquent modelgit 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 也早就做了相干的解决,以是晋级 laravel 后,天然也就不这个成绩了。

以上就是处理晋级php7后isset办法始终为 false的成绩的具体内容,更多请存眷资源魔其它相干文章!

标签: PHP7 isset php7开发教程 php7开发资料 php7开发自学

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