Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah Panggilan Fungsi Lalai Atribut dalam PHP?

Mengapakah Panggilan Fungsi Lalai Atribut dalam PHP?

Susan Sarandon
Susan Sarandonasal
2024-10-17 20:34:02425semak imbas

Why Can't Attribute Defaults Function Calls in PHP?

Tidak Dapat Memanggil Fungsi dalam PHP Atribut Lalai

[Masalah]

Walaupun mempunyai pengalaman pengaturcaraan sebelumnya, seorang pemula dalam PHP bingung dengan ralat lalai atribut. Kod:

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

menghasilkan ralat sintaks. Walau bagaimanapun, perkara berikut berfungsi dengan lancar:

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

Timbul persoalan: mengapa fungsi tidak boleh digunakan dalam lalai atribut? Adakah ini disengajakan atau kecacatan dalam pelaksanaan?

[Jawapan]

Kod pengkompil PHP menunjukkan sekatan ini disengajakan, walaupun tiada rasional rasmi tersedia. Melaksanakan fungsi ini dengan pasti menimbulkan cabaran tertentu, seperti yang dibuktikan oleh pengehadan dalam pelaksanaan semasa PHP.

Tatabahasa pengkompil mentakrifkan pengisytiharan pembolehubah kelas sebagai:

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

Oleh itu, untuk menetapkan nilai pembolehubah seperti $ laluan, nilai yang dijangkakan mesti sejajar dengan skalar statik. Ini merangkumi tatasusunan dengan nilai yang juga skalar statik:

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

Jika tatabahasa membenarkan sintaks berikut, yang sejajar dengan sampel kod, skrip akan menghadapi ralat "Jenis pengikatan tidak sah":

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

Menghuraikan sampel kod yang diberikan mendedahkan langkah berikut:

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

Jika opcode tidak dijangka (cth., berkaitan dengan fungsi atau kaedah), ralat akan dilemparkan.

Membenarkan tatasusunan bukan statik menjana opcode INIT_ARRAY, yang mengganggu zend_do_early_binding():

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

Untuk menampung panggilan fungsi dalam lalai atribut, tatasusunan opcode baharu yang diskop kepada pengisytiharan pembolehubah kelas akan diperlukan, yang serupa kepada definisi kaedah. Walau bagaimanapun, penentuan masa penilaian sedemikian memberikan cabaran tambahan.

Bahasa dinamik lain telah berjaya menyelesaikan masalah ini, tetapi ia kekal sebagai ciri yang tiada dalam PHP, mungkin disebabkan oleh kerumitannya dan dilihat keutamaannya rendah.

Atas ialah kandungan terperinci Mengapakah Panggilan Fungsi Lalai Atribut dalam PHP?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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