Maison  >  Article  >  développement back-end  >  Résolvez le problème selon lequel la méthode isset est toujours fausse après la mise à niveau vers php7

Résolvez le problème selon lequel la méthode isset est toujours fausse après la mise à niveau vers php7

藏色散人
藏色散人avant
2019-03-29 17:15:342944parcourir

Un problème est survenu après la mise à niveau de php7 par l'entreprise, quelque chose comme ça  isset($post->user->name)  était toujours false Le php 5.6 précédent était normal et la version de Laravel était 5.1.35 (elle n'a pas été mise à niveau depuis longtemps). .

Jetons un coup d'œil d'abordisset

isset est utilisé pour détecter si la variable est définie

Jetons d'abord un coup d'œil à un exemple officiel

signifie à peu près ce qui suit

<?php

class Post
{
    protected $attributes = [&#39;content&#39; => &#39;foobar&#39;];

    public function __get($key)
    {
        if (isset($this->attributes[$key])) {
            return $this->attributes[$key];
        }
    }
}

$post = new Post();
echo isset($post->content);  // false

L'exemple ci-dessus renverra toujours false, car foo n'est pas un attribut de Post , mais est retiré de __get

Méthode magique __isset

Alors comment résoudre le problème ci-dessus ? Utiliser la méthode magique

<?PHP
class Post
{
    protected $attributes = [&#39;content&#39; => &#39;foobar&#39;];

    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

Un exemple similaire à Eloquent

En regardant le code de laravel 5.1.35, nous écrivons nous-mêmes un exemple simple

Il y a d'abord aModel, mise en œuvre simple. __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;
    }
}

Ensuite, nous définissons un Post Moel et un User Moel

class Post extends Model
{

    protected function user()
    {
        $user = new User();
        $user->name = &#39;user name&#39;;
        return $user;
    }

}

class User extends Model
{
}

D'accord, vérifions-le isset

$post = new Post();

echo &#39;isset 发帖用户:&#39;;
echo isset($post->user) ? &#39;true&#39; : &#39;false&#39;;  // false
echo PHP_EOL;

echo &#39;isset 发帖用户的名字:&#39;;
echo isset($post->user->name) ? &#39;true&#39; : &#39;false&#39;;  // false
echo PHP_EOL;

echo &#39;发帖用户的名字:&#39;;
echo $post->user->name;    // user name
echo PHP_EOL;

echo &#39;再次判断 isset 发帖用户的名字:&#39;;
echo isset($post->user->name) ? &#39;true&#39; : &#39;false&#39;;   // true
echo PHP_EOL;

Réponse

En analysant les résultats ci-dessus, il semble que le jugement de l'objet par la méthode php 7 isset a changé s'il est exécuté une fois, $post->user->name, c'est-à-dire mettre l'utilisateur dans post de relations , de sorte que isset($post->user) devienne true, puis isset($post->user->name) devienne true.

Enfin trouvé la réponse dans Eloquent model de 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&#39;s comment (core PHP dev) - 
https://bugs.php.net/bug.php?id=69659

c'est à peu près quand php7 juge, il jugera dans l'ordre. php5.6 préchargera les relations. En fait, Laravel a déjà effectué le traitement associé, donc après la mise à niveau de Laravel, ce problème disparaîtra naturellement.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer
Article précédent:Qu’est-ce que PHP7 ?Article suivant:Qu’est-ce que PHP7 ?