Catatan penerjemah. Nikita Popov telah dan terus memberikan kontribusi besar bagi pengembangan bahasa PHP. Dia memahami bagian dalam mesin PHP dengan sangat baik dan dalam artikel ini dia menjelaskan beberapa fitur PHP dalam kaitannya dengan evaluasi urutan ekspresi, yang, mungkin, tidak secara khusus ditemukan di mana pun. Artikel ini sudah berumur sekitar 7 tahun dan bisa dibilang belum kehilangan relevansinya, namun agak susah untuk menemukannya, karena tidak ada di blog Nikita Popov, melainkan sudah dimuat di intinya di github. Saya pikir akan berguna untuk mempresentasikannya kepada komunitas dalam bahasa Rusia.
Di komunitas reddit favorit saya lolphp, saya menemukan postingan di mana orang-orang terkejut dengan hasil kode berikut:
<?php
$a = 1;
$c = $a + $a++;
var_dump($c); // int(3)
$a = 1;
$c = $a + $a + $a++;
var_dump($c); // int(3)
Seperti yang Anda lihat, ekspresi ($a + $a++)
dan ($a + $a + $a++)
memberikan hasil yang sama, yang cukup tidak terduga. Apa yang terjadi di sini?
Prioritas dan asosiatif operator
Banyak orang berpikir bahwa urutan ekspresi yang dievaluasi ditentukan oleh presedensi dan asosiasi operator , tetapi sebenarnya tidak demikian. Prioritas dan asosiatif hanya menentukan urutan operasi yang dikelompokkan dalam ekspresi.
Pada ekspresi pertama, $c = $a + $a++;
post-increment "++" didahulukan dari "+", jadi $ a ++ adalah grup terpisah:
$c = $a + ($a++);
$c = $a + $a + $a++;
- "++" , "+":
$c = $a + $a + ($a++);
"+" - , "+" :
$c = ($a + $a) + ($a++);
: , .
? . , , . , , ($a + $a)
, ($a++)
.
PHP . PHP , β . , - .
CV
-, , PHP , , ( PHP).
(compiled variables, CV), PHP 5.1. (, $a
, $a->b
$a['b']
) . β , PHP , Zend VM ( Zend). 2 .
, .
$a + $a + $a++
:
// code:
$a = 1;
$c = ($a + $a) + ($a++);
// opcodes:
ASSIGN $a, 1
$tmp_1 = ADD $a, $a
$tmp_2 = POST_INC $a
$tmp_3 = ADD $tmp_1, $tmp_2
ASSIGN $c, $tmp_3
:
-
$a = 1
, - β
$a + $a
$tmp_1
, - -
$a
$tmp_2
, - , ,
$c
.
( $a + $a
, $a++
), , , .
$a + $a++
:
// code:
$a = 1;
$c = $a + ($a++);
// opcodes:
ASSIGN $a, 1
$tmp_1 = POST_INC $a
$tmp_2 = ADD $a, $tmp_1
ASSIGN $c, $tmp_2
, POST_INC ($a++)
, $a
ADD
. ? . . CV .
CV
: , CV - @
. PHP 5.x, PHP 7 . , PHP 5 , , - - CV CV.
() , CV , , @
.
. $a + $a++
, , @
:
<?php
$a = 1;
@ $c = $a + $a++;
var_dump($c); // int(2)
, , 3 2. , :
ASSIGN $a, 1
$tmp_1 = BEGIN_SILENCE
$var_3 = FETCH_R 'a'
$tmp_4 = POST_INC $a
$tmp_5 = ADD $var_3, $tmp_4
$var_2 = FETCH_W 'c'
ASSIGN $var_2, $tmp_5
END_SILENCE $tmp_1
, . -, BEGIN_SILENCE
END_SILENCE
. . -, $a
$b
FETCH_R
( ) FETCH_W
( ) .
, $a
, .
CV , , .
. $a + $a++
, :
<?php
$a = [1];
$c = $a[0] + $a[0]++;
var_dump($c); // int(2)
, , 3 2. , :
ASSIGN $a, [1]
$tmp_3 = FETCH_DIM_R 'a', 0
$var_4 = FETCH_DIM_RW 'a', 0
$tmp_5 = POST_INC $var_4
$tmp_6 = ADD $tmp_3, $tmp_5
ASSIGN $c, $tmp_6
, FETCH_DIM_R
( ) FETCH_DIM_RW
( /) .
, , , .
, . 3v4l.org.
- , :
- . .
- Operator
@
menonaktifkan pengoptimalan CV dan akibatnya menurunkan kinerja. Operator@
pada prinsipnya buruk untuk kinerja.
~ nikic
Catatan penerjemah: seperti yang dikatakan di atas, ini @
menonaktifkan pengoptimalan CV hanya di 5.x, di PHP 7 pengoptimalan CV berlangsung bahkan jika operator penekan kesalahan digunakan (tapi mungkin ini tidak terjadi di semua kasus). Nikita Popov memiliki postingan blog yang menarik, Static Optimization di PHP 7 , jika seseorang ingin menggali lebih dalam tentang topik optimasi.