isset en PHP7

Guanhui
Guanhuiavant
2020-05-09 11:09:092874parcourir

Après la mise à jour de php7, quelque chose ne va pas avec isset($post->user-> name) est toujours faux

Le PHP 5.6 précédent était normal

Le laravel la version est 5.1.35 (elle n'a pas été mise à jour depuis longtemps)

Regardez d'abord isset

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

Tout d'abord, regardons un exemple officiel

Cela signifie en gros 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

Ce qui précède L'exemple retournera toujours false, car foo n'est pas une propriété de Post, mais celui retiré par __get

méthode magique __isset

Alors comment résoudre le problème ci-dessus ? Utilisez 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

D'abord un modèle, 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 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 la méthode isset PHP 7 ait modifié le jugement de l'objet. Si elle est exécutée une fois, $post->user->name, c'est-à-dire que l'utilisateur est placé dans le relations de la publication, de sorte que isset ($post->user) soit vrai, puis isset ($post->user->name) soit vrai.

J'ai enfin trouvé la réponse dans le git log du modèle Eloquent,

PHP 7 a corrigé un bug avec __isset qui affecte à la fois les méthodes

isset natives et vides . Cela provoque des problèmes spécifiques

lors de la vérification d'isset ou de vide sur les relations dans Eloquent. Dans

PHP 7, vérifier si une propriété existe sur une relation non chargée,

par exemple isset(. $this->relation->id) renvoie toujours

faux car contrairement à PHP 5.6, PHP 7

vérifie désormais le décalage de chaque attribut avant de le chaîner à

le suivant. Dans PHP 5.6, il chargerait la relation

sans vérifier le décalage. Ce changement ramène le

comportement prévu de la méthode __isset du modèle Eloquent de base

pour PHP 7, donc cela fonctionne comme dans PHP 5.6.

Pour référence, veuillez consulter le lien suivant,

en particulier le commentaire de Nikita Popov (développeur PHP principal) -

https://bugs.php.net/bug.php?id=69659

En gros, lorsque l'isset php7 sera jugé, il sera jugé dans l'ordre. php5.6 préchargera les relations. En fait, Laravel a également effectué le traitement associé dès mai, donc après la mise à niveau de Laravel, ce problème disparaîtra naturellement.

Tutoriels recommandés : "

Tutoriel PHP7

" "
Tutoriel PHP

" "

Tutoriel Laravel

"

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