Operadores de comparação, como os seus nomes implicam, permitem que você
compare dois valores. Você pode se interessar em ver
as tabelas de comparação de tipos,
que tem exemplo das várias comparações entre tipos relacionadas.
Operadores de comparação
Exemplo
Nome
Resultado
$a == $b
Igual
true se $a é igual a $b após equalização de tipos.
$a === $b
Idêntico
true se $a é igual a $b, e eles são do mesmo
tipo.
$a != $b
Diferente
true se $a não é igual a $b depois de equalização de ativos.
$a <> $b
Diferente
true se $a não é igual a $b depois de equalização de ativos.
$a !== $b
Não idêntico
true se $a não é igual a $b, ou eles não são do mesmo
tipo.
Um int menor que, igual a ou maior que zero quando
$a é, respectivamente, menor que, igual a ou maior
que $b.
Se ambos os operadores são
strings numéricas,
ou um operando é um número e o outro é uma
string numérica,
então a comparação é realizada numericamente.
Estas regras se aplicam à instrução
switch.
A conversão de tipos não é realizada quando a comparação é realizada através
=== ou !== porque aqui
é realizada a comparação de tipos, além de valores.
Aviso
Anteriormente ao PHP 8.0.0, se uma string era comparada a um número
ou uma string numérica, então a string era convertida para
número antes de realizar a comparação. Isto pode levar a resultados
inesperados, como observado no exemplo a seguir:
Array com menos membros é menor, se a chave do operando 1 não é
encontrada no operando 2, então os arrays são incomparáveis, caso contrário compara
valor por valor (veja o seguinte exemplo)
<?php // bool e null são sempre comparados como booleanos var_dump(1 == TRUE); // TRUE - o mesmo que (bool) 1 == TRUE var_dump(0 == FALSE); // TRUE - o mesmo que (bool) 0 == FALSE var_dump(100 < TRUE); // FALSE - o mesmo que (bool) 100 < TRUE var_dump(-10 < FALSE);// FALSE - o mesmo que (bool) -10 < FALSE var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool) NULL < (bool) -100 é FALSE < TRUE ?>
Exemplo #3 Transcrição do padrão de comparação de array
<?php // Arrays são comparados assim quando utilizando-se os operadores padrão e operador nave-espacial function standard_array_compare($op1, $op2) { if (count($op1) < count($op2)) { return -1; // $op1 < $op2 } elseif (count($op1) > count($op2)) { return 1; // $op1 > $op2 } foreach ($op1 as $key => $val) { if (!array_key_exists($key, $op2)) { return 1; } elseif ($val < $op2[$key]) { return -1; } elseif ($val > $op2[$key]) { return 1; } } return 0; // $op1 == $op2 } ?>
Aviso
Comparison of floating point numbers
Por conta da forma que floats são representados internamente não
se deve testar dois floats com o comparador de igualdade.
Nota:
Cuidado. A conversão automática de tipos do PHP não é sempre tão óbiva, quando comparando valores de tipos diferentes,
particularmente comparando ints para bools ou ints para strings. No geral é
recomendado utilizar as comparações === e !== em vez de utilizar
== e != na maioria dos casos.
Embora a comparação de identidade (=== e !==)
possa ser aplicada para valores arbitrários, os outros operadores de comparação somente devem
ser aplicados a valores comparáveis. O resultado de comparação de valores não comparáveis
não é definida, e não pode ser garantida.
// O código acima é idêntico a esta instrução if/else if (empty($_POST['action'])) { $action = 'default'; } else { $action = $_POST['action']; } ?>
A expressão (expr1) ? (expr2) : (expr3)
é avaliada para expr2 se
expr1 é avaliada como true, ou
expr3 se
expr1 é avaliada como false.
É possível deixar vazia a parte central do operador ternário.
A expressão expr1 ?: expr3 retorna
o resultado de expr1 se expr1
avaliar para true, e expr3 se não.
expr1 somente é avaliada nessa única situação.
Nota:
Note que o operador ternário é uma expressão, e ele não é
avaliado para uma variável, mas para o resultado de uma expressão. Isto é
importante saber se você quer retornar uma variável por referência.
A declaração return $var == 42 ? $a : $b; em uma
função que retorna por referência conseqüêntemente não irá funcionar e será
avisado.
Nota:
É recomendado evitar empilhar operadores ternários.
O comportamento do PHP quando utilizando mais de um operador ternário sem parênteses numa única
expressão é menos óbvia, comparada a outras linguagesn.
Antes do PHP 8.0.0, os operadores ternários eram avaliados com associatividade à esquerda,
em vez de associatividade à direta, como na maioria de outras linguagens.
Depender da associatividade à esquerda foi descontinuado a partir do PHP 7.4.0.
A partir do PHP 8.0.0, o operador ternário é não associativo.
Exemplo #5 Comportamento não óbvio do ternário
<?php // Pode parecer que a expressão a seguir imprime 'true' echo (true ? 'true' : false ? 't' : 'f');
// No entanto, a saída é na verdade 't' antes do PHP 8.0.0 // Isto ocorre porque operadores ternários são associativos à esquerda
// O seguinte é a versão mais intuitiva do código acima echo ((true ? 'true' : false) ? 't' : 'f');
// Aqui, é possível ver que a primeira expressão avalia para 'true', e então // é avalidada para (bool) true, e portanto retorna o variante true da // segunda expressão ternária ?>
Nota:
Encadeamento de ternários curtos (?:), é estável, e comporta-se intuitivamente.
Ele avaliará como o primeiro argumento que avalia para uma valor não falso. Observe que valores
não definidos irão emitir um alerta.
// O conteúdo acima é idêntico à essa declaração if/else if (isset($_POST['action'])) { $action = $_POST['action']; } else { $action = 'default'; } ?>
A expressão (expr1) ?? (expr2) é avaliada para
expr2 se expr1 for
null, e expr1 do contrário.
Esse operador em particular não emite aviso caso o valor da esquerda
não exista, assim como isset(). Sendo especialmente
útil em chaves de arrays.
Nota:
Note que o operador null coalescing é uma expressão, e ele
não é avaliado para uma variável, mas para o resultado de uma expressão. Isto
é importante saber se você quer retornar uma variável por referência.
A declaração return $foo ?? $bar; em uma
função que retorna por referência conseqüêntemente não irá funcionar e será
avisado.
Nota:
O operador de aglutinação null tem baixa precedência. Isso significa que misturá-lo
com outros operadores (como por exemplo concatenação ou aritmética)
irá provavelmente exigir parênteses.
<?php // Emite um aviso que $name não está definido. print 'Mr. ' . $name ?? 'Anonymous';
Please note that using the null coalescing operator to check properties on a class that has the __get magic method (without an __isset magic method) invokes the magic method.
For example:
<?php
class A { public function __get($property) { echo 'Called __get for ' . $property . PHP_EOL; } }
Note: according to the spec, PHP's comparison operators are not transitive. For example, the following are all true in PHP5:
"11" < "a" < 2 < "11"
As a result, the outcome of sorting an array depends on the order the elements appear in the pre-sort array. The following code will dump out two arrays with *different* orderings:
You can't just compare two arrays with the === operator
like you would think to find out if they are equal or not. This is more complicated when you have multi-dimensional arrays. Here is a recursive comparison function.
<?php
/**
* Compares two arrays to see if they contain the same values. Returns TRUE or FALSE.
* usefull for determining if a record or block of data was modified (perhaps by user input)
* prior to setting a "date_last_updated" or skipping updating the db in the case of no change.
*
* @param array $a1
* @param array $a2
* @return boolean
*/
function array_compare_recursive($a1, $a2)
{
if (!(is_array($a1) and (is_array($a2)))) { return FALSE;}
if (!count($a1) == count($a2))
{
return FALSE; // arrays don't have same number of entries
}
foreach ($a1 as $key => $val)
{
if (!array_key_exists($key, $a2))
{return FALSE; // uncomparable array keys don't match
}
elseif (is_array($val) and is_array($a2[$key])) // if both entries are arrays then compare recursive
{if (!array_compare_recursive($val,$a2[$key])) return FALSE;
}
elseif (!($val === $a2[$key])) // compare entries must be of same type.
{return FALSE;
}
}
return TRUE; // $a1 === $a2
}
?>
A related, but more strict problem, is if you need to ensure that two arrays contain the same key=>value pairs, regardless of the order of the pairs. In that case, use:
Please be careful when you try to compare strings that have a plus sign `+` at the beginning (such as phone number, etc). When you use the Equal operator `==` PHP will ignore the plus sign. Use Identical operator `===` instead
Care must be taken when using the spaceship operator with arrays that do not have the same keys:
- Contrary to the notes above ("Example #2 Transcription of standard array comparison"), it does *not* return null if the left-hand array contains a key that the right-hand array does not. - Because of this, the result depends on the order you do the comparison in.
Between the "shortcut ternary" (aka "elvis") and "spaceship" operators, you can write some quite compact comparison functions for usort and its ilk.
If you want to sort an array of associative arrays by several different keys you can chain them in the same way that you can list column names in an SQL ORDER BY clause.
<?php usort($array, fn($a, $b) => $a['a'] <=> $b['a'] ?: $b['b'] <=> $a['b'] ?: $a['c'] <=> $b['c']); ?> Will sort the array by column 'a', then by column 'b' descending, then by column 'c'; or in SQL-speak 'ORDER BY a, b DESC, c".
In the table "Comparison with Various Types", please move the last line about "Object" to be above the line about "Array", since Object is considered to be greater than Array (tested on 5.3.3)
(Please remove my "Anonymous" post of the same content before. You could check IP to see that I forgot to type my name)
It's worth noting that there can be a difference in the logical operation of shorthand ternary (expr1 ?: expr2) vs the full version (expr1 ? expr1 : expr2). The shorthand style may also offer a slight performance enhancement because the initial expression will only be evaluated once.
Example: <?php // my_func() will be called twice here // additionally, my_func() may not return the same value both times! $var = my_func() ? my_func() : false;
// my_func() will only be called once here $var = my_func() ?: false;