首頁  >  文章  >  後端開發  >  為什麼 PHP 中的函數呼叫不能使用屬性預設值?

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

Susan Sarandon
Susan Sarandon原創
2024-10-17 20:34:02424瀏覽

Why Can't Attribute Defaults Function Calls in PHP?

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

[問題]

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

<code class="php">class Foo {
    public $path = array(
        realpath(".")
    );
}</code>

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

<code class="php">$path = array(
    realpath(".")
);</code>

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

[答案]

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

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

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

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

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 中仍然缺乏此功能,可能是由於其複雜性和感知的低優先級。

以上是為什麼 PHP 中的函數呼叫不能使用屬性預設值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn