搜尋
首頁後端開發PHP7解決升級php7後isset方法始終為 false的問題

公司升級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

上面這個例子將永遠回傳 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

類似

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 = &#39;user name&#39;;
        return $user;
    }

}

class User extends Model
{
}

好了來驗證一下

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;

答案

分析上面的結果,感覺像是php 7

isset 方法對物件的判斷有了變化,如果先執行一次,$post->user->name,也就是將user 放在post#在 ## 的relations 中,這樣isset($post->user) true,接著 isset($post->user- >name) 才為true最後在

Eloquent model

git log 找到了答案,<pre class='brush:php;toolbar:false;'>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-&gt;relation-&gt;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&amp;#39;s comment (core PHP dev) - https://bugs.php.net/bug.php?id=69659</pre>大致上是 php7 isset 判斷的時候,會依次判斷。 php5.6 則會預先載入關係。其實 laravel 也早就做了相關的處理,所以升級 laravel 後,自然就沒有這個問題了。

以上是解決升級php7後isset方法始終為 false的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:learnku。如有侵權,請聯絡admin@php.cn刪除
如何從PHP 5.6升級到PHP 7?如何從PHP 5.6升級到PHP 7?Mar 10, 2025 pm 06:29 PM

本文詳細介紹了將PHP 5.6升級為PHP 7的升級,並強調了關鍵步驟,例如備份,檢查服務器兼容性以及選擇升級方法(軟件包管理器,編譯,控制面板或Web服務器配置)。 它解決了Potentia

如何使用New Relic等工具監視PHP 7的性能?如何使用New Relic等工具監視PHP 7的性能?Mar 10, 2025 pm 06:28 PM

本文解釋瞭如何使用新遺物監視PHP 7應用程序性能。 它詳細詳細介紹了新的Relic的設置,關鍵績效指標(KPI),例如APDEX分數和響應時間,通過交易軌蹟的瓶頸標識和錯誤軌跡

如何將PHP 7應用程序部署到Web服務器?如何將PHP 7應用程序部署到Web服務器?Mar 10, 2025 pm 06:28 PM

本文詳細介紹了部署PHP 7應用程序,涵蓋方法(FTP,SSH,部署工具),服務器配置(Apache/nginx,php-fpm),數據庫設置和重要的安全考慮因素。 它突出了服務器compatib等常見挑戰

如何在PHP 7項目中使用GIT進行版本控制?如何在PHP 7項目中使用GIT進行版本控制?Mar 10, 2025 pm 06:27 PM

本文指導PHP 7開發人員使用GIT進行版本控制。 它涵蓋了初始化,分期,投入,忽略文件,遠程存儲庫,分支,合併,解決衝突和基本的GIT命令。 效率的最佳實踐

如何使用PHP 7使用Docker?如何使用PHP 7使用Docker?Mar 10, 2025 pm 06:26 PM

本文解釋了使用具有PHP 7的Docker,涵蓋了Dockerfile的創建,圖像構建和容器運行時。 它詳細介紹了安全性最佳實踐(非根本用戶,依賴關係更新,輸入驗證),使用Docker Comp的多服務管理

如何使用Xdebug進行調試PHP 7代碼?如何使用Xdebug進行調試PHP 7代碼?Mar 10, 2025 pm 06:26 PM

本文說明瞭如何使用Xdebug進行調試PHP 7代碼。 它涵蓋Xdebug配置(安裝,php.ini設置,IDE設置),斷點用法(條件,功能,遠程)和故障排除連接問題。 有效的Debuggi

如何使用PHPUNIT測試PHP 7代碼?如何使用PHPUNIT測試PHP 7代碼?Mar 10, 2025 pm 06:25 PM

本文指導PHP開發人員使用PHPUNIT測試PHP 7代碼。 它突出了從先前的PHP版本的無縫過渡,強調利用PHP 7的功能(類型提示,返回類型)以改善測試魯棒性。 文章

如何使用PHP 7使用CodeIgniter框架?如何使用PHP 7使用CodeIgniter框架?Mar 10, 2025 pm 06:24 PM

本文指導使用PHP 7的Codeigniter指導該框架的兼容性,PHP 7的發動機增強功能以​​及至關重要的安全性最佳實踐。 它涵蓋了設置,配置和利用PHP 7 Featu

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用