Rumah > Artikel > pembangunan bahagian belakang > Mengapakah Panggilan Fungsi Lalai Atribut dalam PHP?
[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!