Gelagat Panggilan Fungsi Samar-samar dalam PHP: Mendedahkan Nuansa Tersembunyi
Dalam PHP, tingkah laku pelik timbul apabila menggunakan fungsi dan merangkum hasilnya dalam kurungan. Tindakan yang kelihatan tidak berbahaya ini boleh mengubah tafsiran hasil, yang berpotensi membawa kepada tingkah laku yang tidak dijangka.
Pertimbangkan coretan kod berikut:
error_reporting(E_ALL | E_STRICT); function get_array() { return array(); } function foo() { return reset(get_array()); // Error: "Only variables should be passed by reference" return reset((get_array())); // Success } foo();
Dalam varian pertama, cuba memberikan hasil get_array() ke fungsi reset() mencetuskan ralat, kerana ia sepatutnya pembolehubah yang diluluskan oleh rujukan. Walau bagaimanapun, apabila kita membungkus panggilan fungsi dalam kurungan, skrip berjalan dengan jayanya.
Walaupun seseorang mungkin membuat spekulasi tentang mekanik asas, pemeriksaan menyeluruh terhadap dokumentasi gagal memberikan penjelasan yang jelas untuk fenomena ini.
Menyelidiki dengan lebih mendalam kerumitan tatabahasa PHP dan menggunakan alatan seperti phc untuk memvisualisasikan AST kod mendedahkan bahawa kedua-dua coretan menghasilkan pepohon parse yang sama. Ini menghapuskan kemungkinan pengubahsuaian sintaksis yang mempengaruhi gelagat.
Walau bagaimanapun, pemeriksaan lebih dekat struktur opcode PHP mendedahkan kaveat tersembunyi dalam opcode ZEND_SEND_VAR_NO_REF. Opcode ini menetapkan bahawa ralat rujukan tidak boleh dilemparkan apabila argumen bukan panggilan fungsi dan mempunyai kiraan rujukan 1.
Dalam varian kedua foo(), panggilan fungsi tidak lagi dikenali kerana kepada kurungan tambahan. Akibatnya, sistem mengklasifikasikan hujah sebagai expr_without_variable dan memulakan opcode SEND_VAR_NO_REF. Memandangkan tatasusunan yang dikembalikan mempunyai kiraan rujukan 1, ia dianggap sesuai sebagai pembolehubah, dengan itu mengelakkan ralat rujukan.
Adalah penting untuk ambil perhatian bahawa tingkah laku ini harus dianggap sebagai pepijat dan bukan ciri yang dimaksudkan . Bergantung pada ketidakkonsistenan sedemikian boleh membawa kepada kod yang tidak dapat diramalkan dan tidak boleh dipercayai.
Atas ialah kandungan terperinci Mengapa Membungkus Panggilan Fungsi dalam Tanda Kurung Mengelakkan Ralat Rujukan dalam PHP?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!