mirror of
https://github.com/php/doc-es.git
synced 2026-03-23 23:12:09 +01:00
557 lines
16 KiB
XML
557 lines
16 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: 16934048f79c6e117cd16a23c09c1b2ea502e284 Maintainer: PhilDaiguille Status: ready -->
|
|
<!-- Reviewed: no -->
|
|
<sect1 xml:id="language.operators.comparison">
|
|
<title>Operadores de comparación</title>
|
|
<titleabbrev>Comparación</titleabbrev>
|
|
<simpara>
|
|
Los operadores de comparación, como su nombre indica,
|
|
permiten comparar dos valores. También se debe estar interesado por las
|
|
<link linkend="types.comparisons">tablas de comparaciones de tipos</link>,
|
|
ya que muestran ejemplos de muchos tipos de comparaciones.
|
|
</simpara>
|
|
<table>
|
|
<title>Operadores de comparación</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Ejemplo</entry>
|
|
<entry>Nombre</entry>
|
|
<entry>Resultado</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>$a == $b</entry>
|
|
<entry>Igual</entry>
|
|
<entry>&true; si <varname>$a</varname> es igual a
|
|
<varname>$b</varname> después del transtipado.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a === $b</entry>
|
|
<entry>Idéntico</entry>
|
|
<entry>
|
|
&true; si <varname>$a</varname> es igual a <varname>$b</varname> y
|
|
son del mismo tipo.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a != $b</entry>
|
|
<entry>Diferente</entry>
|
|
<entry>&true; si <varname>$a</varname> es diferente de
|
|
<varname>$b</varname> después del transtipado.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <> $b</entry>
|
|
<entry>Diferente</entry>
|
|
<entry>&true; si <varname>$a</varname> es diferente de
|
|
<varname>$b</varname> después del transtipado.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a !== $b</entry>
|
|
<entry>Diferente</entry>
|
|
<entry>
|
|
&true; si <varname>$a</varname> es diferente de <varname>$b</varname>
|
|
o bien si no son del mismo tipo.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a < $b</entry>
|
|
<entry>Menor que</entry>
|
|
<entry>&true; si <varname>$a</varname> es estrictamente menor que
|
|
<varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a > $b</entry>
|
|
<entry>Mayor</entry>
|
|
<entry>&true; si <varname>$a</varname> es estrictamente mayor que
|
|
<varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <= $b</entry>
|
|
<entry>Menor o igual</entry>
|
|
<entry>&true; si <varname>$a</varname> es menor o igual a
|
|
<varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a >= $b</entry>
|
|
<entry>Mayor o igual</entry>
|
|
<entry>&true; si <varname>$a</varname> es mayor o igual a
|
|
<varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <=> $b</entry>
|
|
<entry>Combinado</entry>
|
|
<entry>
|
|
Un &integer; menor, igual o mayor a cero cuando
|
|
<varname>$a</varname> es menor, igual, o mayor a
|
|
<varname>$b</varname> respectivamente.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
Si los dos operandos son
|
|
<link linkend="language.types.numeric-strings">strings numéricos</link>,
|
|
o si un operando es un número y el otro es un
|
|
<link linkend="language.types.numeric-strings">string numérico</link>,
|
|
entonces la comparación se efectuará numéricamente.
|
|
Estas reglas también se aplican a la instrucción
|
|
<link linkend="control-structures.switch">switch</link>.
|
|
La conversión de tipo no interviene cuando la comparación es
|
|
<literal>===</literal> o <literal>!==</literal>
|
|
ya que esto implica tanto una comparación de tipo como de valor.
|
|
</para>
|
|
|
|
<warning>
|
|
<para>
|
|
Antes de PHP 8.0.0, si un <type>string</type> es comparado a un número
|
|
o a un string numérico, entonces el <type>string</type> será convertido en un
|
|
número antes de efectuar la comparación. Esto puede llevar a resultados
|
|
sorprendentes como se puede ver en el siguiente ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
var_dump(0 == "a");
|
|
var_dump("1" == "01");
|
|
var_dump("10" == "1e1");
|
|
var_dump(100 == "1e2");
|
|
|
|
switch ("a") {
|
|
case 0:
|
|
echo "0";
|
|
break;
|
|
case "a":
|
|
echo "a";
|
|
break;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.7;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
bool(true)
|
|
bool(true)
|
|
0
|
|
]]>
|
|
</screen>
|
|
&example.outputs.8;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(false)
|
|
bool(true)
|
|
bool(true)
|
|
bool(true)
|
|
a
|
|
]]>
|
|
</screen>
|
|
</informalexample>
|
|
</para>
|
|
</warning>
|
|
|
|
<para>
|
|
<example>
|
|
<title>Operadores de comparación</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Enteros
|
|
echo 1 <=> 1, ' '; // 0
|
|
echo 1 <=> 2, ' '; // -1
|
|
echo 2 <=> 1, ' '; // 1
|
|
|
|
// Números flotantes
|
|
echo 1.5 <=> 1.5, ' '; // 0
|
|
echo 1.5 <=> 2.5, ' '; // -1
|
|
echo 2.5 <=> 1.5, ' '; // 1
|
|
|
|
// Strings
|
|
echo "a" <=> "a", ' '; // 0
|
|
echo "a" <=> "b", ' '; // -1
|
|
echo "b" <=> "a", ' '; // 1
|
|
|
|
echo "a" <=> "aa", ' '; // -1
|
|
echo "zz" <=> "aa", ' '; // 1
|
|
|
|
// Arrays
|
|
echo [] <=> [], ' '; // 0
|
|
echo [1, 2, 3] <=> [1, 2, 3], ' '; // 0
|
|
echo [1, 2, 3] <=> [], ' '; // 1
|
|
echo [1, 2, 3] <=> [1, 2, 1], ' '; // 1
|
|
echo [1, 2, 3] <=> [1, 2, 4], ' '; // -1
|
|
|
|
// Objetos
|
|
$a = (object) ["a" => "b"];
|
|
$b = (object) ["a" => "b"];
|
|
echo $a <=> $b, ' '; // 0
|
|
|
|
$a = (object) ["a" => "b"];
|
|
$b = (object) ["a" => "c"];
|
|
echo $a <=> $b, ' '; // -1
|
|
|
|
$a = (object) ["a" => "c"];
|
|
$b = (object) ["a" => "b"];
|
|
echo $a <=> $b, ' '; // 1
|
|
|
|
// No solo las valores son comparados; las claves deben coincidir
|
|
$a = (object) ["a" => "b"];
|
|
$b = (object) ["b" => "b"];
|
|
echo $a <=> $b, ' '; // 1
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
Para los diferentes tipos, la comparación se realiza siguiendo
|
|
la tabla siguiente (en orden).
|
|
</para>
|
|
<table xml:id="language.operators.comparison.types">
|
|
<title>Comparación con múltiples tipos</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Tipo del operando 1</entry>
|
|
<entry>Tipo del operando 2</entry>
|
|
<entry>Resultado</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry><type>null</type> o <type>string</type></entry>
|
|
<entry><type>string</type></entry>
|
|
<entry>Convierte &null; en "", comparación numérica o léxica</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>bool</type> o <type>null</type></entry>
|
|
<entry>Cualquier cosa</entry>
|
|
<entry>Convierte en <type>bool</type>, &false; < &true;</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>object</type></entry>
|
|
<entry><type>object</type></entry>
|
|
<entry>Las clases internas pueden definir su propio método de
|
|
comparación; diferentes clases son incomparables; entre objetos
|
|
de la misma clase ver <link
|
|
linkend="language.oop5.object-comparison">Comparación de objetos</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>
|
|
&string;, &resource;, &integer; o &float;
|
|
</entry>
|
|
<entry>
|
|
&string;, &resource;, &integer; o &float;
|
|
</entry>
|
|
<entry>
|
|
Transforma los strings y los recursos en números
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>array</type></entry>
|
|
<entry><type>array</type></entry>
|
|
<entry>El array con menos miembros es menor, si la clave del operando 1 no es encontrada en el operando 2, entonces los arrays son incomparables, de lo contrario la comparación se realiza valor por valor (ver el siguiente ejemplo)
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>object</type></entry>
|
|
<entry>Cualquier cosa</entry>
|
|
<entry>El <type>objeto</type> es siempre mayor</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>array</type></entry>
|
|
<entry>Cualquier cosa</entry>
|
|
<entry>El <type>array</type> es siempre mayor</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
|
|
<para>
|
|
<example>
|
|
<title>Comparación Booléen/null</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Booléen y null siempre son comparados como booléans
|
|
var_dump(1 == TRUE); // TRUE - idéntico a (bool) 1 == TRUE
|
|
var_dump(0 == FALSE); // TRUE - idéntico a (bool) 0 == FALSE
|
|
var_dump(100 < TRUE); // FALSE - idéntico a (bool) 100 < TRUE
|
|
var_dump(-10 < FALSE);// FALSE - idéntico a (bool) -10 < FALSE
|
|
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool) NULL < (bool) -100 es idéntico a FALSE < TRUE
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
<example>
|
|
<title>Transcripción de las comparaciones estándar de arrays</title>
|
|
<programlisting role="php" annotations="non-interactive">
|
|
<![CDATA[
|
|
<?php
|
|
// Los arrays son comparados de esta manera con los operadores estándar de comparación y el operador combinado
|
|
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
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<warning>
|
|
<title>Comparación de números de punto flotante</title>
|
|
|
|
<para>
|
|
Debido a la forma en que los números de punto flotante son representados
|
|
internamente, no se debe probar la igualdad entre dos números de tipo
|
|
<type>float</type>.
|
|
</para>
|
|
|
|
<para>
|
|
Ver la documentación de <type>float</type> para más información.
|
|
</para>
|
|
</warning>
|
|
|
|
<note>
|
|
<simpara>
|
|
Tenga en cuenta que la manipulación de tipos no siempre es evidente al comparar
|
|
valores de diferentes tipos, en particular al comparar &integer;s con &boolean;s o
|
|
&integer;s con &string;s. Por lo tanto, generalmente se recomienda utilizar los
|
|
operadores de comparación <literal>===</literal> y <literal>!==</literal> en lugar de
|
|
<literal>==</literal> y <literal>!=</literal> en la mayoría de los casos.
|
|
</simpara>
|
|
</note>
|
|
|
|
<sect2 xml:id="language.operators.comparison.incomparable">
|
|
<title>Valores incomparables</title>
|
|
<simpara>
|
|
Mientras que las comparaciones de identidad (<literal>===</literal> y <literal>!==</literal>)
|
|
pueden ser aplicadas a valores arbitrarios, los otros operadores de
|
|
comparación solo deben ser aplicados a valores comparables.
|
|
El resultado de la comparación de valores incomparables es indefinido,
|
|
y no debe ser utilizado.
|
|
</simpara>
|
|
</sect2>
|
|
|
|
<sect2 role="seealso">
|
|
&reftitle.seealso;
|
|
<para>
|
|
<simplelist>
|
|
<member><function>strcasecmp</function></member>
|
|
<member><function>strcmp</function></member>
|
|
<member><link linkend="language.operators.array">operador de arrays</link></member>
|
|
<member><link linkend="language.types">Tipos</link></member>
|
|
</simplelist>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.operators.comparison.ternary">
|
|
<title>El operador ternario</title>
|
|
<para>
|
|
Otro operador condicional es el operador
|
|
ternario ("?:").
|
|
<example>
|
|
<title>Asignación de un valor por defecto</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Ejemplo de uso para el operador ternario
|
|
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
|
|
|
|
// La línea anterior es idéntica a la siguiente condición:
|
|
if (empty($_POST['action'])) {
|
|
$action = 'default';
|
|
} else {
|
|
$action = $_POST['action'];
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
La expresión <literal>(expr1) ? (expr2) : (expr3)</literal>
|
|
se evalúa a <replaceable>expr2</replaceable> si
|
|
<replaceable>expr1</replaceable> se evalúa a &true;, y
|
|
<replaceable>expr3</replaceable> si
|
|
<replaceable>expr1</replaceable> se evalúa a &false;.
|
|
</para>
|
|
<para>
|
|
Es posible omitir la parte central del operador ternario.
|
|
La expresión <literal>expr1 ?: expr3</literal> evalúa el resultado de
|
|
<replaceable>expr1</replaceable> si <replaceable>expr1</replaceable>
|
|
vale &true;, y <replaceable>expr3</replaceable> en caso contrario.
|
|
<replaceable>expr1</replaceable> solo se evalúa una vez en este caso.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Tenga en cuenta que el operador ternario es una expresión, y no
|
|
se evalúa como una variable, sino como el resultado de la expresión.
|
|
Es importante saberlo si se desea devolver una variable
|
|
por referencia. La instrucción
|
|
<literal>return $var == 42 ? $a : $b;</literal>
|
|
en una función devuelta por referencia no funcionará y se emitirá una alerta.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Se recomienda no "apilar" las expresiones ternarias.
|
|
El comportamiento de PHP al utilizar varios operadores
|
|
ternarios que no están entre paréntesis en una única expresión es
|
|
no evidente en comparación con otros lenguajes.
|
|
Anteriormente a PHP 8.0.0, el operador ternario se evaluaba
|
|
de izquierda a derecha, en lugar de derecha a izquierda como la mayoría de
|
|
los otros lenguajes de programación.
|
|
Dependiendo de la asociatividad a la izquierda es obsoleto a partir de PHP 7.4.0.
|
|
A partir de PHP 8.0.0, el operador ternario no es asociativo.
|
|
<example>
|
|
<title>Comportamiento de PHP</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// A primera vista, lo siguiente debería devolver 'true'
|
|
echo (true ? 'true' : false ? 't' : 'f');
|
|
|
|
// sin embargo, la expresión anterior devolverá 't' antes de PHP 8.0.0
|
|
// porque el operador ternario es de izquierda a derecha
|
|
|
|
// la siguiente expresión es una versión más evidente del mismo código
|
|
echo ((true ? 'true' : false) ? 't' : 'f');
|
|
|
|
// aquí, se puede observar que la primera expresión se evalúa a 'true',
|
|
// lo que hace que se evalúe a (bool)true, lo que devuelve la rama
|
|
// 'verdadera' de la segunda expresión ternaria.
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
La combinación de ternario corto (<literal>?:</literal>), sin embargo, es estable y se comporta de manera razonable.
|
|
Esto evaluará el primer argumento que evalúa a un valor no-falsy.
|
|
Tenga en cuenta que los valores indefinidos siempre emitirán un aviso.
|
|
<example>
|
|
<title>Combinación de ternario corto</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
|
|
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2
|
|
echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="language.operators.comparison.coalesce">
|
|
<title>Operador de fusión Null</title>
|
|
<para>
|
|
Otro operador corto útil es el operador "??" (o fusión null).
|
|
<example>
|
|
<title>Asignar un valor por defecto</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Ejemplo de uso para: Operador de fusión Null
|
|
$action = $_POST['action'] ?? 'default';
|
|
|
|
// el código anterior es equivalente a la siguiente estructura if/else
|
|
if (isset($_POST['action'])) {
|
|
$action = $_POST['action'];
|
|
} else {
|
|
$action = 'default';
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
La expresión <literal>(expr1) ?? (expr2)</literal> devuelve
|
|
<replaceable>expr2</replaceable> si <replaceable>expr1</replaceable> es
|
|
&null;, y <replaceable>expr1</replaceable> en los otros casos.
|
|
</para>
|
|
<para>
|
|
En particular, este operador no emite una notificación o advertencia si
|
|
la parte izquierda no existe, exactamente como <function>isset</function>.
|
|
Esto es especialmente útil para las claves de los arrays.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Tenga en cuenta que el operador de fusión null es una expresión, y que
|
|
no se evalúa como una variable, sino como el resultado de una expresión.
|
|
Es importante saberlo si se desea devolver una variable
|
|
por referencia.
|
|
La expresión <literal>return $foo ?? $bar;</literal> es un retorno por
|
|
referencia que no funciona y emite una advertencia.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
El operador de fusión null tiene una precedencia baja. Esto significa que al mezclarlo
|
|
con otros operadores (como la concatenación de strings o los operadores
|
|
aritméticos) se requerirán paréntesis.
|
|
</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Emite una advertencia de que $name es indefinida.
|
|
print 'Mr. ' . $name ?? 'Anonymous';
|
|
|
|
// Imprime "Mr. Anonymous"
|
|
print 'Mr. ' . ($name ?? 'Anonymous');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Tenga en cuenta que el operador de fusión null permite una imbricación simple:
|
|
<example>
|
|
<title>Imbricación de la operación de fusión null</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$foo = null;
|
|
$bar = null;
|
|
$baz = 1;
|
|
$qux = 2;
|
|
|
|
echo $foo ?? $bar ?? $baz ?? $qux; // salida 1
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
</sect2>
|
|
|
|
</sect1>
|