」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 為什麼 PHP 中的函數呼叫不能使用屬性預設值?

為什麼 PHP 中的函數呼叫不能使用屬性預設值?

發佈於2024-11-06
瀏覽:708

Why Can\'t Attribute Defaults Function Calls in PHP?

無法在PHP 屬性預設值中呼叫函數

[問題]

儘管有程式設計經驗,但新手PHP中的屬性預設錯誤令我困惑。代碼:

class Foo {
    public $path = array(
        realpath(".")
    );
}

產生文法錯誤。但是,以下內容可以無縫運行:

$path = array(
    realpath(".")
);

問題出現了:為什麼不能在屬性預設值中呼叫函數?這是故意的還是實現中的缺陷?

[答案]

PHP 編譯器程式碼顯示此限制是故意的,儘管沒有官方的理由。可靠地實現此功能會帶來一定的挑戰,PHP 目前實現的限制就證明了這一點。

編譯器的語法將類別變數宣告定義為:

class_variable_declaration:
      //...
      | T_VARIABLE '=' static_scalar //...
;

因此,要指派像 $path 這樣的變數值,預期值必須與靜態標量對齊。這包括其值也是靜態標量的陣列:

static_scalar: /* compile-time evaluated scalars */
      //...
      | T_ARRAY '(' static_array_pair_list ')' // ...
      //...
;

如果語法允許使用以下與程式碼範例一致的語法,則腳本將遇到「無效的綁定類型」錯誤:

class_variable_declaration:
      //...
      | T_VARIABLE '=' T_ARRAY '(' array_pair_list ')' // ...
;

解析給定的程式碼範例顯示以下步驟:

zend_do_begin_class_declaration() // Adds an opcode
array_init(), zend_do_add_static_array_element() // Do not create new opcodes, add array to class properties
zend_do_declare_property() // Declares the property
zend_do_early_binding() // Consumes the last opcode and evaluates it

如果操作碼不是預期的(例如,與函數或方法相關),則會拋出錯誤。

允許非靜態陣列產生一個 INIT_ARRAY 操作碼,它會破壞 zend_do_early_binding():

DECLARE_CLASS   'Foo'
SEND_VAL        '.'
DO_FCALL        'realpath'
INIT_ARRAY

為了適應屬性預設值中的函數調用,需要一個作用域為類別變數聲明的新操作碼數組,類似於方法定義。然而,確定此類評估的時機提出了額外的挑戰。

其他動態語言已經設法解決了這個問題,但它仍然是 PHP 中缺少的功能,可能是由於其複雜性和感知的低優先級。

版本聲明 本文轉載於:1729168219如有侵犯,請洽[email protected]刪除
最新教學 更多>
  • 如何在 HTML 中自訂選擇清單選項的懸停背景?
    如何在 HTML 中自訂選擇清單選項的懸停背景?
    在HTML 中自訂選擇清單選項懸停背景使用HTML 選擇清單時,調整選項的預設外觀可能會很有幫助懸停以獲得更好的用戶體驗。但是,嘗試使用「option:hover」CSS 屬性來變更選擇清單選項的背景顏色可能是徒勞無功的。這是因為瀏覽器為這些元素維護預設背景顏色,從而覆蓋自訂樣式。 一種解決方法是利...
    程式設計 發佈於2024-11-06
  • 如何在不重新啟動伺服器的情況下啟用MySQL慢查詢日誌?
    如何在不重新啟動伺服器的情況下啟用MySQL慢查詢日誌?
    如何在不重啟伺服器的情況下啟用MySQL慢查詢日誌問:我只能使用http推薦的方法設定慢查詢閾值://crazytoon.com/2007/07/23/。還需要什麼嗎,例如指定檔案路徑? A:根據MySQL文檔,預設的慢查詢日誌文件名稱為host_name-slow.log,位於資料目錄下。如果您在...
    程式設計 發佈於2024-11-06
  • 如何在 C++ 中不使用 new 來建立物件並呼叫建構函式?
    如何在 C++ 中不使用 new 來建立物件並呼叫建構函式?
    建構子和Malloc建構子和Malloc與new 和delete 表達式不同,std::malloc 在為物件分配記憶體時不會呼叫建構函數。因此,要在創建物件的同時呼叫其建構函數,需要另一種方法。 可能的解決方案:1。利用 new:這是主要的預期用法,因為 new 明確建立一個物件並隨後呼叫其建構函...
    程式設計 發佈於2024-11-06
  • 如何在Python中散列大檔案而不消耗記憶體?
    如何在Python中散列大檔案而不消耗記憶體?
    在Python中計算大檔案的MD5雜湊值Python的hashlib模組為計算加密雜湊值提供了一個方便的接口。然而,對於大小超過系統記憶體的特別大的文件,直接使用 hashlib 可能會出現問題。 解決方案:漸進式哈希為了解決這個問題,我們採用漸進式哈希通過以可管理的區塊讀取檔案。這種方法可確保對整...
    程式設計 發佈於2024-11-06
  • 使用 Maven 以及 PostgreSQL 資料庫對 Java Spring Boot 應用程式進行 Docker 化
    使用 Maven 以及 PostgreSQL 資料庫對 Java Spring Boot 應用程式進行 Docker 化
    Docker化 Spring Boot 應用程式涉及建立包含您的應用程式及其相依性的 Docker 映像。這允許您以一種可以輕鬆共享並在任何安裝了 Docker 的電腦上運行的方式打包應用程式。以下是對基於 Maven 的 Spring Boot 應用程式進行 Docker 化並在 Docker 容...
    程式設計 發佈於2024-11-06
  • 如何修復由 Google JAR 檔案引起的 Android Studio 中的“GC Overhead Limit Exceeded”錯誤?
    如何修復由 Google JAR 檔案引起的 Android Studio 中的“GC Overhead Limit Exceeded”錯誤?
    Google JAR 檔案導致Android Studio 中出現GC 開銷限制超出錯誤Android Studio 使用者在下列情況下可能會遇到「GC開銷限制超出”錯誤使用Google JAR 檔案。此問題通常是由於 dedex 進程分配的記憶體不足而引起的。要解決此問題,請考慮以下步驟:1.增加...
    程式設計 發佈於2024-11-06
  • 如何用 SQLSRV 取代 PHP 5.3 中已棄用的 MSSQL 擴充?
    如何用 SQLSRV 取代 PHP 5.3 中已棄用的 MSSQL 擴充?
    PHP 5.3 中MSSQL 擴展的替代方案隨著PHP 5.3 中MSSQL 擴展的棄用,尋求替代解決方案變得至關重要。本文深入研究 SQLSRV 擴充功能作為連接 Microsoft SQL 資料庫的可行選項。 根據 PHP 手冊,PHP 5.3 及更高版本不再支援 MSSQL 擴充。作為替代,M...
    程式設計 發佈於2024-11-06
  • 何時使用 AtomicBoolean:防止多執行緒應用程式中的資料不一致?
    何時使用 AtomicBoolean:防止多執行緒應用程式中的資料不一致?
    AtomicBoolean:Volatile Boolean 的更強大的替代品在多線程編程中,確保對共享數據的正確和一致的訪問至關重要。一種常見的方法是使用 volatile 關鍵字將欄位標記為共享,確保對變數的變更對其他執行緒立即可見。但是, volatile 關鍵字存在一些限制,可能會導致問題,...
    程式設計 發佈於2024-11-06
  • Jsoup 如何讓 Java 中的網頁抓取變得簡單又有效率?
    Jsoup 如何讓 Java 中的網頁抓取變得簡單又有效率?
    Java 中網頁抓取的HTML 解析在軟體開發領域,有必要從網站中提取有價值的資訊以用於各種目的。這種從線上來源提取資料的過程通常稱為網頁抓取。 Java 程式設計師可以使用多功能工具來完成此任務:HTML 解析器。 強烈建議的 Java HTML 解析器是 Jsoup。它的出色之處在於其用戶友好的...
    程式設計 發佈於2024-11-06
  • Jetmaker - 用於以 Python 建構分散式系統的開源框架
    Jetmaker - 用於以 Python 建構分散式系統的開源框架
    專案:Jetmaker 它是 Python 開發人員將多個分散式節點連接到一個系統中的框架,因此分散式應用程式可以存取彼此的資料和服務。它還提供了同步所有節點的工具,就像在多線程和多處理中所做的那樣 Github連結:https://github.com/gavinwei121/Jetmaker 文...
    程式設計 發佈於2024-11-06
  • 馴服電子郵件野獸:我的收件匣管理人工智慧之旅
    馴服電子郵件野獸:我的收件匣管理人工智慧之旅
    是否曾经感觉您的收件箱是一个数字九头蛇,为您回复的每个人发送两封新电子邮件? ??好吧,科技爱好者们,我决定用秘密武器来对付这个怪物:人工智能! ??️ 尤里卡时刻 想象一下:现在是凌晨 3 点,我周围都是空咖啡杯☕☕☕,盯着一个数量可与国会图书馆相媲美的收件箱。就在那时,我突然想到...
    程式設計 發佈於2024-11-06
  • 為什麼 Go 是智能合約開發的新競爭者
    為什麼 Go 是智能合約開發的新競爭者
    区块链生态系统迅速发展,引入了创新的解决方案和平台,扩展了分布式账本技术的潜力。这项创新的核心是智能合约——自动执行的程序,无需中介即可自动执行协议。传统上,Solidity 一直是编写智能合约的首选语言,尤其是以太坊区块链。 Solidity 旨在在以太坊虚拟机 (EVM) 中运行,为开发人员提供...
    程式設計 發佈於2024-11-06
  • 如何在等待執行緒完成時保持 tkinter GUI 回應?
    如何在等待執行緒完成時保持 tkinter GUI 回應?
    等待線程完成時凍結/掛起tkinter GUI在Python 中使用tkinter GUI 工具包時遇到的常見問題執行某些操作時介面凍結或掛起。這通常是由於在主事件循環中使用了阻塞操作,例如加入執行緒。 瞭解 tkinter Mainlooptkinter mainloop() 是負責處理使用者輸入...
    程式設計 發佈於2024-11-06
  • C 和 C++ 中條件運算子的行為有什麼不同?
    C 和 C++ 中條件運算子的行為有什麼不同?
    條件運算子:剖析C 與C 的差異在程式設計領域,條件運算子(?:) 充當計算表達式並根據結果傳回特定值的簡潔方法。雖然此運算符在 C 和 C 中的操作類似,但出現了一個微妙的區別,可能會影響程式碼執行。 C:對左值的限制在 C 中,條件運算子會對傳回左值(駐留在特定記憶體位址的變數)施加限制。這表示...
    程式設計 發佈於2024-11-06
  • Java中如何有效率地檢查字串中是否存在某個字元?
    Java中如何有效率地檢查字串中是否存在某個字元?
    高效字串字元驗證在Java中,一個常見的任務是判斷某個特定字元是否出現在字串中。雖然傳統方法涉及遍歷字串,但利用 indexOf() 的有效替代方法消除了循環的需要。 IndexOf() 逐個字元掃描字串,並傳回指定字元所在的第一個實例的索引出現。如果該字元不存在,則傳回值 -1。 考慮檢查字元「a...
    程式設計 發佈於2024-11-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3