Esse teste é, na verdade, uma tentativa de resposta para a pergunta:
Existe alguma vantagem ao se utilizar da segunda forma ou é apenas uma questão de estética/semântica?
$itemRecebidoViaPost = $_POST['item'];
// Primeira forma if ( $itemRecebidoViaPost == 'item-desejado' ) {
}
// Segunda forma if ( 'item-desejado' == $itemRecebidoViaPost ) {
}
Além das duas formas, que originaram a pergunta, ainda adicionei um terceiro caso, sobre o if ternário. O opcode é o mesmo para ambos, porém, independentemente de testar if (5 < $a)
ou if ($a > 5)
, o PHP faz a checagem IS_SMALLER 5, !0
, ou seja if ($expected < $actual)
, que também é a lógica empregada pelo PHPUnit e outros frameworks de teste unitário, como JUnit.
Primeiro Caso
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename: /src/1st-case.php
function name: (null)
number of ops: 11
compiled vars: !0 = $a, !1 = $b
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 10
4 2 EXT_STMT
3 IS_SMALLER ~1 5, !0
4 > JMPZ ~1, ->8
5 5 > EXT_STMT
6 ASSIGN !1, 5
6 7 > JMP ->10
7 8 > EXT_STMT
9 ASSIGN !1, 10
9 10 > > RETURN 1
branch: # 0; line: 2- 4; sop: 0; eop: 4; out1: 5; out2: 8
branch: # 5; line: 5- 6; sop: 5; eop: 7; out1: 10
branch: # 8; line: 7- 9; sop: 8; eop: 9; out1: 10
branch: # 10; line: 9- 9; sop: 10; eop: 10
path #1: 0, 5, 10,
path #2: 0, 8, 10,
Segundo Caso
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename: /src/2nd-case.php
function name: (null)
number of ops: 11
compiled vars: !0 = $a, !1 = $b
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 10
4 2 EXT_STMT
3 IS_SMALLER ~1 5, !0
4 > JMPZ ~1, ->8
5 5 > EXT_STMT
6 ASSIGN !1, 5
6 7 > JMP ->10
7 8 > EXT_STMT
9 ASSIGN !1, 10
9 10 > > RETURN 1
branch: # 0; line: 2- 4; sop: 0; eop: 4; out1: 5; out2: 8
branch: # 5; line: 5- 6; sop: 5; eop: 7; out1: 10
branch: # 8; line: 7- 9; sop: 8; eop: 9; out1: 10
branch: # 10; line: 9- 9; sop: 10; eop: 10
path #1: 0, 5, 10,
path #2: 0, 8, 10,
O mesmo não ocorre com uma verificação de igualdade. Nesse tipo de comparação, o opcode gerado segue a lógica empregada no código, por exemplo:
<?php
$a = 10;
if (5 == $a) {
$b = 5;
} else {
$b = 10;
}
Se observar o opcode, IS_EQUAL 5, !0
:
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename: /src/4th-case.php
function name: (null)
number of ops: 11
compiled vars: !0 = $a, !1 = $b
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 10
4 2 EXT_STMT
3 IS_EQUAL ~1 5, !0
4 > JMPZ ~1, ->8
5 5 > EXT_STMT
6 ASSIGN !1, 5
6 7 > JMP ->10
7 8 > EXT_STMT
9 ASSIGN !1, 10
9 10 > > RETURN 1
branch: # 0; line: 2- 4; sop: 0; eop: 4; out1: 5; out2: 8
branch: # 5; line: 5- 6; sop: 5; eop: 7; out1: 10
branch: # 8; line: 7- 9; sop: 8; eop: 9; out1: 10
branch: # 10; line: 9- 9; sop: 10; eop: 10
path #1: 0, 5, 10,
path #2: 0, 8, 10,
Invertendo a ordem da comparação:
<?php
$a = 10;
if ($a == 5) {
$b = 5;
} else {
$b = 10;
}
Se observar o opcode, IS_EQUAL !0, 5
:
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 8
Branch analysis from position: 5
Jump found. Position 1 = 10
Branch analysis from position: 10
Return found
Branch analysis from position: 8
Return found
filename: /src/5th-case.php
function name: (null)
number of ops: 11
compiled vars: !0 = $a, !1 = $b
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 10
4 2 EXT_STMT
3 IS_EQUAL ~1 !0, 5
4 > JMPZ ~1, ->8
5 5 > EXT_STMT
6 ASSIGN !1, 5
6 7 > JMP ->10
7 8 > EXT_STMT
9 ASSIGN !1, 10
9 10 > > RETURN 1
branch: # 0; line: 2- 4; sop: 0; eop: 4; out1: 5; out2: 8
branch: # 5; line: 5- 6; sop: 5; eop: 7; out1: 10
branch: # 8; line: 7- 9; sop: 8; eop: 9; out1: 10
branch: # 10; line: 9- 9; sop: 10; eop: 10
path #1: 0, 5, 10,
path #2: 0, 8, 10,
Agora o if ternário:
Terceiro caso
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 7
Branch analysis from position: 5
Jump found. Position 1 = 8
Branch analysis from position: 8
Return found
Branch analysis from position: 7
Return found
filename: /src/3rd-case.php
function name: (null)
number of ops: 10
compiled vars: !0 = $a, !1 = $b
line # * op fetch ext return operands
---------------------------------------------------------------------------------
2 0 > EXT_STMT
1 ASSIGN !0, 10
3 2 EXT_STMT
3 IS_SMALLER ~1 5, !0
4 > JMPZ ~1, ->7
5 > QM_ASSIGN ~2 5
6 > JMP ->8
7 > QM_ASSIGN ~2 10
8 > ASSIGN !1, ~2
4 9 > RETURN 1
branch: # 0; line: 2- 3; sop: 0; eop: 4; out1: 5; out2: 7
branch: # 5; line: 3- 3; sop: 5; eop: 6; out1: 8
branch: # 7; line: 3- 3; sop: 7; eop: 7; out1: 8
branch: # 8; line: 3- 4; sop: 8; eop: 9
path #1: 0, 5, 8,
path #2: 0, 7, 8,
Analizando o opcode do terceiro caso, teoricamente, mesmo que insignificantemente, ele deveria ser mais rápido. Mas na prática, não dá para afirmar se um é mais rápido que o outro em nenhum dos três casos.
O código foi testado no PHP 5.4.21
PHP 5.4.21 (cli) (built: Oct 17 2013 05:21:08)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
Antes do PHP 5.4, porém, existia uma situação que poderia fazer com que o terceiro caso fosse mais lento em determinadas situações. O PHP fazia uma cópia do conteúdo da variável. Então, se o volume de dados armazenados em uma determinada variável fosse muito grande, então a cópia do conteúdo fazia com que o terceiro caso fosse mais lento. Essa situação não acontecia com objetos, pois o PHP 5.3 já trabalhava com referências para os objetos, mas se fosse uma string muito grande, ou um array muito grande, a cópia do conteúdo faria o terceiro caso mais lento, quando comparado com os dois primeiros.