Maison > développement back-end > PHP7 > 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

藏色散人
Libérer: 2023-02-17 11:46:01
avant
3129 Les gens l'ont consulté

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
Copier après la connexion

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
Copier après la connexion

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;
    }
}
Copier après la connexion

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
{
}
Copier après la connexion

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;
Copier après la connexion

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
Copier après la connexion

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!

Étiquettes associées:
source:learnku.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal