Rumah pembangunan bahagian belakang PHP7 解决升级php7后isset方法始终为 false的问题

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

Mar 29, 2019 pm 05:15 PM
isset php7

公司升级 php7 后出现了一个问题,类似这样 isset($post->user->name) 始终为 false,之前的php 5.6 就很正常,laravel 版本是 5.1.35(很久没升级了)。

先看看isset

isset 用来检测变量是否设置

首先我们来看官方的一个例子

大致上是下面这个意思

<?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
Salin selepas log masuk

上面这个例子将永远返回 false,因为 foo 并不是 Post 的属性,而是 __get 取出来的

魔术方法 __isset

那么怎么解决上面那个问题呢?使用魔术方法

<?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
Salin selepas log masuk

类似 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;
    }
}
Salin selepas log masuk

然后我们定义一个 Post Moel 和一个 User Moel

class Post extends Model
{

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

}

class User extends Model
{
}
Salin selepas log masuk

好了来验证一下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;
Salin selepas log masuk

答案

分析上面的结果,感觉像是 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&#39;s comment (core PHP dev) - 
https://bugs.php.net/bug.php?id=69659
Salin selepas log masuk

大致上是 php7 isset 判断的时候,会依次判断。php5.6 则会预加载关系。其实 laravel 也早就做了相关的处理,所以升级 laravel 后,自然也就没有这个问题了。

Atas ialah kandungan terperinci 解决升级php7后isset方法始终为 false的问题. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk memasang sambungan mongo dalam php7.0 Bagaimana untuk memasang sambungan mongo dalam php7.0 Nov 21, 2022 am 10:25 AM

Cara memasang sambungan mongo dalam php7.0: 1. Buat kumpulan pengguna dan pengguna mongodb 2. Muat turun pakej kod sumber mongodb dan letakkan pakej kod sumber dalam direktori "/usr/local/src/" 3. Masukkan direktori "src/" 4. Buka zip pakej kod sumber 5. Buat direktori fail mongodb 6. Salin fail ke direktori "mongodb/" 7. Buat fail konfigurasi mongodb;

Bagaimana untuk menyelesaikan masalah apabila php7 mengesan bahawa port tcp tidak berfungsi Bagaimana untuk menyelesaikan masalah apabila php7 mengesan bahawa port tcp tidak berfungsi Mar 22, 2023 am 09:30 AM

Dalam php5, kita boleh menggunakan fungsi fsockopen() untuk mengesan port TCP. Fungsi ini boleh digunakan untuk membuka sambungan rangkaian dan melakukan beberapa komunikasi rangkaian. Tetapi dalam php7, fungsi fsockopen() mungkin menghadapi beberapa masalah, seperti tidak dapat membuka port, tidak dapat menyambung ke pelayan, dsb. Untuk menyelesaikan masalah ini, kita boleh menggunakan fungsi socket_create() dan fungsi socket_connect() untuk mengesan port TCP.

Apakah yang perlu saya lakukan jika pemalam dipasang dalam php7.0 tetapi ia masih menunjukkan bahawa ia tidak dipasang? Apakah yang perlu saya lakukan jika pemalam dipasang dalam php7.0 tetapi ia masih menunjukkan bahawa ia tidak dipasang? Apr 02, 2024 pm 07:39 PM

Untuk menyelesaikan pemalam yang tidak menunjukkan isu yang dipasang dalam PHP 7.0: Semak konfigurasi pemalam dan dayakan pemalam. Mulakan semula PHP untuk menggunakan perubahan konfigurasi. Semak kebenaran fail pemalam untuk memastikan ia betul. Pasang kebergantungan yang hilang untuk memastikan pemalam berfungsi dengan betul. Jika semua langkah lain gagal, bina semula PHP. Punca lain yang mungkin termasuk versi pemalam yang tidak serasi, memuatkan versi yang salah atau isu konfigurasi PHP.

PHP menentukan sama ada kunci yang ditentukan wujud dalam tatasusunan PHP menentukan sama ada kunci yang ditentukan wujud dalam tatasusunan Mar 21, 2024 pm 09:21 PM

Artikel ini akan menerangkan secara terperinci bagaimana PHP menentukan sama ada kunci yang ditentukan wujud dalam tatasusunan Editor berpendapat ia sangat praktikal, jadi saya berkongsi dengan anda sebagai rujukan saya harap anda boleh memperoleh sesuatu selepas membaca artikel ini. PHP menentukan sama ada kunci yang ditentukan wujud dalam tatasusunan: Dalam PHP, terdapat banyak cara untuk menentukan sama ada kunci yang ditentukan wujud dalam tatasusunan: 1. Gunakan fungsi isset(): isset($array["key"]) Fungsi ini mengembalikan nilai Boolean, benar jika kunci yang ditentukan wujud, palsu sebaliknya. 2. Gunakan fungsi array_key_exists(): array_key_exists("key",$arr

Cara memasang dan menggunakan php7.0 Cara memasang dan menggunakan php7.0 Nov 30, 2022 am 09:56 AM

Cara memasang dan menggunakan php7.0: 1. Pergi ke laman web rasmi PHP untuk memuat turun versi pemasangan yang sepadan dengan sistem tempatan 2. Ekstrak fail zip yang dimuat turun ke direktori yang ditentukan 3. Buka tetingkap baris arahan dan pergi ke direktori "E:\php7" Hanya jalankan arahan "php -v".

Apr 09, 2024 pm 01:33 PM

Penyelesaian biasa untuk persekitaran pelayan PHP termasuk memastikan versi PHP yang betul dipasang dan fail yang berkaitan telah disalin ke direktori modul. Lumpuhkan SELinux buat sementara waktu atau selama-lamanya. Semak dan konfigurasikan PHP.ini untuk memastikan sambungan yang diperlukan telah ditambah dan disediakan dengan betul. Mulakan atau mulakan semula perkhidmatan PHP-FPM. Semak tetapan DNS untuk isu penyelesaian.

Bagaimana cara menetapkan kebenaran secara automatik UnixSocket selepas sistem dimulakan semula? Bagaimana cara menetapkan kebenaran secara automatik UnixSocket selepas sistem dimulakan semula? Mar 31, 2025 pm 11:54 PM

Bagaimana untuk menetapkan keizinan UnixSocket secara automatik selepas sistem dimulakan semula. Setiap kali sistem dimulakan semula, kita perlu melaksanakan perintah berikut untuk mengubahsuai keizinan UnixSocket: sudo ...

Mengapa ralat berlaku semasa memasang pelanjutan menggunakan PECL dalam persekitaran Docker? Bagaimana menyelesaikannya? Mengapa ralat berlaku semasa memasang pelanjutan menggunakan PECL dalam persekitaran Docker? Bagaimana menyelesaikannya? Apr 01, 2025 pm 03:06 PM

Punca dan penyelesaian untuk kesilapan Apabila menggunakan PECL untuk memasang sambungan dalam persekitaran Docker Apabila menggunakan persekitaran Docker, kami sering menemui beberapa sakit kepala ...

See all articles