Urutan evaluasi dalam PHP

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.



PHP 5.x

() , 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.





- , :



  1. . .
  2. 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.




All Articles