mirror of
https://github.com/php/doc-es.git
synced 2026-03-26 00:12:06 +01:00
git-svn-id: https://svn.php.net/repository/phpdoc/es/trunk@338335 c90b9560-bf6c-de11-be94-00142212c4b1
2380 lines
69 KiB
XML
2380 lines
69 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: f99e5eb6c7081af49f2ecc1a7cbe7b7e39565d9e Maintainer: seros Status: ready -->
|
|
<!-- Reviewed: no Maintainer: andresdzphp -->
|
|
<chapter xml:id="language.operators" xmlns="http://docbook.org/ns/docbook">
|
|
<title>Operadores</title>
|
|
<simpara>
|
|
Un operador es algo que toma uno más valores (o
|
|
expresiones, en la jerga de programación) y produce otro valor (de modo que la
|
|
construcción en si misma se convierte en una expresión).
|
|
</simpara>
|
|
<para>
|
|
Los operadores se pueden agrupar de acuerdo con el número de valores que toman. Los operadores
|
|
unarios toman sólo un valor, por ejemplo <literal>!</literal> (el
|
|
<link linkend="language.operators.logical">operador lógico de negación</link>) o
|
|
<literal>++</literal> (el
|
|
<link linkend="language.operators.increment">operador de incremento</link>).
|
|
Los operadores binarios toman dos valores, como los familiares
|
|
<link linkend="language.operators.arithmetic">operadores aritméticos</link>
|
|
<literal>+</literal> (suma) y <literal>-</literal> (resta), y la
|
|
mayoría de los operadores de PHP entran en esta categoría. Finalmente, hay sólo
|
|
un <link linkend="language.operators.comparison.ternary">operador
|
|
ternario</link>, <literal>? :</literal>, el cual toma tres valores; usualmente a este se
|
|
le refiere simplemente como "el operador ternario" (aunque podría
|
|
tal vez llamarse más correctamente como el operador condicional).
|
|
</para>
|
|
<para>
|
|
Una lista completa de operadores de PHP sigue en la sección
|
|
<link linkend="language.operators.precedence">Precedencia de Operadores</link>.
|
|
La sección también explica la precedencia y asociatividad de los operadores, las cuales gobiernan
|
|
exactamente cómo son evaluadas expresiones que contienen varios diferentes
|
|
operadores.
|
|
</para>
|
|
|
|
<sect1 xml:id="language.operators.precedence">
|
|
<title>Precedencia de operadores</title>
|
|
<para>
|
|
La precedencia de un operador indica qué tan "estrechamente" se unen dos
|
|
expresiones juntas. Por ejemplo, en la expresión <literal>1 +
|
|
5 * 3 </literal>, la respuesta es <literal>16</literal> y no
|
|
<literal>18</literal> porque el operador de multiplicación ("*")
|
|
tiene una precedencia mayor que el operador de adición ("+").
|
|
Los paréntesis pueden ser usados para forzar la precedencia, si es necesario. Por
|
|
ejemplo: <literal>(1 + 5) * 3</literal> se evalúa como
|
|
<literal>18</literal>.
|
|
</para>
|
|
<para>
|
|
Cuando los operadores tienen igual precedencia su asociatividad decide
|
|
cómo se agrupan. Por ejemplo "-" tiene asociatividad a izquierda, así
|
|
<literal>1 - 2 - 3</literal> se agrupa como <literal>(1 - 2) - 3</literal>
|
|
y se evalúa a <literal>-4</literal>. "=", por otra parte, tiene
|
|
asociatividad a derecha, así <literal>$a = $b = $c</literal> se agrupa como
|
|
<literal>$a = ($b = $c)</literal>.
|
|
</para>
|
|
<para>
|
|
Los operadores de igual precedencia que no son asociativos no pueden usarse
|
|
unos junto a otros, por ejemplo, <literal>1 < 2 > 1</literal> es
|
|
ilegal en PHP. La expresión <literal>1 <= 1 == 1</literal>, por otro
|
|
lado, es legal, ya que el operador <literal>==</literal> tiene menos
|
|
precedencia que el operador <literal><=</literal>.
|
|
</para>
|
|
<para>
|
|
El uso de paréntesis, incluso cuando no es estrictamente necesario, a menudo puede
|
|
aumentar la legibilidad del código haciendo grupos explícitamente en lugar de confiar
|
|
en la precedencia y asociatividad implícitas del operador.
|
|
</para>
|
|
<para>
|
|
La siguiente tabla enumera los operadores en orden de precedencia, con
|
|
los de más alta precedencia al inicio. Los operadores en la misma línea
|
|
tienen igual precedencia, en cuyo caso la asociatividad decide el agrupamiento.
|
|
<table>
|
|
<title>Precedencia de operadores</title>
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>Asociatividad</entry>
|
|
<entry>Operadores</entry>
|
|
<entry>Información adicional</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>no asociativo</entry>
|
|
<entry>
|
|
<literal>clone</literal>
|
|
<literal>new</literal>
|
|
</entry>
|
|
<entry><link linkend="language.oop5.cloning">clone</link> and <link linkend="language.oop5.basic.new">new</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>[</literal></entry>
|
|
<entry><function>array</function></entry>
|
|
</row>
|
|
<row>
|
|
<entry>derecha</entry>
|
|
<entry><literal>**</literal></entry>
|
|
<entry><link linkend="language.operators.arithmetic">aritmética</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>derecha</entry>
|
|
<entry>
|
|
<literal>++</literal>
|
|
<literal>--</literal>
|
|
<literal>~</literal>
|
|
<literal>(int)</literal>
|
|
<literal>(float)</literal>
|
|
<literal>(string)</literal>
|
|
<literal>(array)</literal>
|
|
<literal>(object)</literal>
|
|
<literal>(bool)</literal>
|
|
<literal>@</literal>
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.types">tipos</link> e <link linkend="language.operators.increment">incremento/decremento</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>no asociativo</entry>
|
|
<entry><literal>instanceof</literal></entry>
|
|
<entry>
|
|
<link linkend="language.types">tipos</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>derecha</entry>
|
|
<entry><literal>!</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">lógico</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry>
|
|
<literal>*</literal>
|
|
<literal>/</literal>
|
|
<literal>%</literal>
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.operators.arithmetic">aritmética</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry>
|
|
<literal>+</literal>
|
|
<literal>-</literal>
|
|
<literal>.</literal>
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.operators.arithmetic">aritmética</link>&listendand;
|
|
<link linkend="language.operators.string">string</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry>
|
|
<literal><<</literal>
|
|
<literal>>></literal>
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bit a bit</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>no asociativo</entry>
|
|
<entry>
|
|
<literal><</literal>
|
|
<literal><=</literal>
|
|
<literal>></literal>
|
|
<literal>>=</literal>
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.operators.comparison">comparación</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>no asociativo</entry>
|
|
<entry>
|
|
<literal>==</literal>
|
|
<literal>!=</literal>
|
|
<literal>===</literal>
|
|
<literal>!==</literal>
|
|
<literal><></literal>
|
|
<literal><=></literal>
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.operators.comparison">comparación</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>&</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bit a bit</link>&listendand;
|
|
<link linkend="language.references">referencias</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>^</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bit a bit</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>|</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bit a bit</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>&&</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">lógico</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>||</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">lógico</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>derecha</entry>
|
|
<entry><literal>??</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.comparison">comparación</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>? :</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.comparison.ternary">ternario</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>derecha</entry>
|
|
<entry>
|
|
<literal>=</literal>
|
|
<literal>+=</literal>
|
|
<literal>-=</literal>
|
|
<literal>*=</literal>
|
|
<literal>**=</literal>
|
|
<literal>/=</literal>
|
|
<literal>.=</literal>
|
|
<literal>%=</literal>
|
|
<literal>&=</literal>
|
|
<literal>|=</literal>
|
|
<literal>^=</literal>
|
|
<literal><<=</literal>
|
|
<literal>>>=</literal>
|
|
<literal>=></literal>
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.operators.assignment">asignación</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>and</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">lógico</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>xor</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">lógico</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>or</literal></entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">lógico</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>izquierda</entry>
|
|
<entry><literal>,</literal></entry>
|
|
<entry>muchos usos</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Asociatividad</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
|
|
// la asociatividad del operador ternario difiere de C/C++
|
|
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
|
|
|
|
$a = 1;
|
|
$b = 2;
|
|
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
La precedencia y asociatividad de los operadores solamente determinan cómo
|
|
se agrupan las expresiones, no especifican un orden de evaluación. PHP no
|
|
especifica (en general) el orden en que se evalúa una expresión
|
|
y se debería evitar el código que se asume un orden específico de evaluación,
|
|
ya que el comportamiento puede cambiar entre versiones de PHP o dependiendo de
|
|
código circundante.
|
|
<example>
|
|
<title>Orden de evaluación no definido</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = 1;
|
|
echo $a + $a++; // podría mostrar 2 o 3
|
|
|
|
$i = 1;
|
|
$array[$i] = $i++; // podría establecer el índice a 1 o 2
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Aunque <literal>=</literal> tiene una precedencia menor que
|
|
la mayoría de los demás operadores, PHP aun permitirá expresiones
|
|
similares a lo siguiente: <literal>if (!$a = foo())</literal>,
|
|
en cuyo caso el valor devuelto de <literal>foo()</literal> es
|
|
puesto en <varname>$a</varname>.
|
|
</para>
|
|
</note>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.arithmetic">
|
|
<title>Operadores aritméticos</title>
|
|
<simpara>
|
|
¿Recuerda la aritmética básica de la escuela? Estos funcionan
|
|
igual que aquellos.
|
|
</simpara>
|
|
<table>
|
|
<title>Operadores aritméticos</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Ejemplo</entry>
|
|
<entry>Nombre</entry>
|
|
<entry>Resultado</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>-$a</entry>
|
|
<entry>Negación</entry>
|
|
<entry>Opuesto de <varname>$a</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a + $b</entry>
|
|
<entry>Adición</entry>
|
|
<entry>Suma de <varname>$a</varname> y <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a - $b</entry>
|
|
<entry>Sustracción</entry>
|
|
<entry>Diferencia de <varname>$a</varname> y <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a * $b</entry>
|
|
<entry>Multiplicación</entry>
|
|
<entry>Producto de <varname>$a</varname> y <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a / $b</entry>
|
|
<entry>División</entry>
|
|
<entry>Cociente de <varname>$a</varname> y <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a % $b</entry>
|
|
<entry>Módulo</entry>
|
|
<entry>Resto de <varname>$a</varname> dividido por <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a ** $b</entry>
|
|
<entry>Exponenciación</entry>
|
|
<entry>Resultado de elevar <varname>$a</varname> a la potencia <varname>$b</varname>ésima. Introducido en PHP 5.6.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<simpara>
|
|
El operador de división ("/") devuelve un valor flotante a menos que los dos operandos
|
|
sean integers (o strings que se conviertan a integers) y los números
|
|
sean divisibles, en cuyo caso será devuelto un valor integer.
|
|
</simpara>
|
|
<simpara>
|
|
Los operandos del módulo se convierten en integers (por extracción de la parte
|
|
decimal) antes del procesamiento.
|
|
</simpara>
|
|
<para>
|
|
El resultado del operador módulo <literal>%</literal> tiene el mismo signo
|
|
que el dividendo — es decir, el resultado de <literal>$a % $b</literal>
|
|
tendrá el mismo signo que <varname>$a</varname>. Por ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
echo (5 % 3)."\n"; // muestra 2
|
|
echo (5 % -3)."\n"; // muestra 2
|
|
echo (-5 % 3)."\n"; // muestra -2
|
|
echo (-5 % -3)."\n"; // muestra -2
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Véase también la página del manual sobre
|
|
<link linkend="ref.math">funciones matemáticas</link>.
|
|
</simpara>
|
|
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.assignment">
|
|
<title>Operadores de asignación</title>
|
|
<simpara>
|
|
El operador básico de asignación es "=". Se podría inclinar a pensar
|
|
primero que es como un "igual a". No lo es. Realmente significa que el
|
|
operando de la izquierda se establece con el valor de la expresión de la
|
|
derecha (es decir, "se define como").
|
|
</simpara>
|
|
<para>
|
|
El valor de una expresión de asignación es el valor asignado. Es
|
|
decir, el valor de "<literal>$a = 3</literal>" es de 3. Esto permite hacer algunas cosas
|
|
intrincadas:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$a = ($b = 4) + 5; // ahora $a es igual a 9 y $b se ha establecido en 4.
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Para <type>arrays</type>, asignar un valor a una clave con nombre se realiza utilizando
|
|
el operador "=>". La <link linkend="language.operators.precedence">precedencia</link>
|
|
de este operador es la misma que otros operadores de asignación.
|
|
</para>
|
|
<para>
|
|
Además del operador básico de asignación, existen "operadores
|
|
combinados" para todos los de <link linkend="language.operators">aritmética
|
|
binaria</link>, unión de arrays y operadores de strings que permiten usar un valor en una
|
|
expresión y entonces establecer su valor como el resultado de esa expresión. Por
|
|
ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$a = 3;
|
|
$a += 5; // establece $a en 8, como si se hubiera dicho: $a = $a + 5;
|
|
$b = "Hola ";
|
|
$b .= "ahí!"; // establece $b en "Hola ahí!", al igual que $b = $b . "ahí!";
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Observe que la asignación copia la variable original en la nueva
|
|
(asignación por valor), por lo que los cambios en una no afectarán a la
|
|
otra. Esto también puede tener relevancia si se necesita copiar algo
|
|
como un gran array dentro de un bucle estrecho.
|
|
</para>
|
|
<para>
|
|
Una excepción al comportamiento usual de la asignación por valor en PHP ocurre
|
|
con <type>object</type>s los cuales son asignados por referencia en PHP 5.
|
|
Los objetos pueden ser explícitamente copiados por medio de la palabra clave
|
|
<link linkend="language.oop5.cloning">clone</link>.
|
|
</para>
|
|
|
|
<sect2 xml:id="language.operators.assignment.reference">
|
|
<title>Asignación por referencia</title>
|
|
<para>
|
|
La asignación por referencia también está soportada, utilizando la
|
|
sintaxis "<computeroutput>$var = &$othervar;</computeroutput>".
|
|
Asignación por referencia significa que ambas variables terminan apuntando a los
|
|
mismos datos y nada es copiado en ninguna parte.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Asignación por referencia</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = 3;
|
|
$b = &$a; // $b es una referencia para $a
|
|
|
|
print "$a\n"; // muestra 3
|
|
print "$b\n"; // muestra 3
|
|
|
|
$a = 4; // cambia $a
|
|
|
|
print "$a\n"; // muestra 4
|
|
print "$b\n"; // muestra 4 también, dado que $b es una referencia para $a, la cual ha
|
|
// sido cambiada
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Desde PHP 5, el operador <link linkend="language.oop5.basic.new">new</link>
|
|
retorna una referencia automáticamente, así que asignar el resultado de
|
|
<link linkend="language.oop5.basic.new">new</link> por referencia, resulta
|
|
en un mensaje <constant>E_DEPRECATED</constant> en PHP 5.3 y posteriores y
|
|
un mensaje <constant>E_STRICT</constant> en versiones anteriores.
|
|
</para>
|
|
<para>
|
|
Por ejemplo, éste código resultará en una advertencia:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class C {}
|
|
|
|
/* La siguiente línea genera el siguiente mensaje de error:
|
|
* Deprecated: Assigning the return value of new by reference is deprecated in...
|
|
*/
|
|
$o = &new C;
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Más información sobre referencias y sus usos potenciales se puede encontrar en
|
|
la sección del manual
|
|
<link linkend="language.references">Referencias Explicadas</link>
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.bitwise">
|
|
<title>Operadores bit a bit</title>
|
|
<simpara>
|
|
Los operadores bit a bit permiten la evaluación y la manipulación de bits
|
|
específicos dentro de un integer.
|
|
</simpara>
|
|
<table>
|
|
<title>Operadores bit a bit</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Ejemplo</entry>
|
|
<entry>Nombre</entry>
|
|
<entry>Resultado</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry><userinput>$a & $b</userinput></entry>
|
|
<entry>And (y)</entry>
|
|
<entry>Los bits que están activos en ambos <varname>$a</varname> y <varname>$b</varname> son activados.</entry>
|
|
</row>
|
|
<row>
|
|
<entry><userinput>$a | $b</userinput></entry>
|
|
<entry>Or (o inclusivo)</entry>
|
|
<entry>Los bits que están activos ya sea en <varname>$a</varname> o en <varname>$b</varname> son activados.</entry>
|
|
</row>
|
|
<row>
|
|
<entry><userinput>$a ^ $b</userinput></entry>
|
|
<entry>Xor (o exclusivo)</entry>
|
|
<entry>
|
|
Los bits que están activos en <varname>$a</varname> o en <varname>$b</varname>, pero no en ambos, son activados.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry><userinput>~ $a</userinput></entry>
|
|
<entry>Not (no)</entry>
|
|
<entry>
|
|
Los bits que están activos en <varname>$a</varname> son desactivados, y viceversa.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry><userinput>$a << $b</userinput></entry>
|
|
<entry>Shift left(desplazamiento a izquierda)</entry>
|
|
<entry>
|
|
Desplaza los bits de <varname>$a</varname>, <varname>$b</varname> pasos a la izquierda (cada paso
|
|
quiere decir "multiplicar por dos").
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry><userinput>$a >> $b</userinput></entry>
|
|
<entry>Shift right (desplazamiento a derecha)</entry>
|
|
<entry>
|
|
Desplaza los bits de <varname>$a</varname>, <varname>$b</varname> pasos a la derecha (cada paso
|
|
quiere decir "dividir por dos").
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
El desplazamiento de bits en PHP es aritmético.
|
|
Los bits desplazados por fuera de cualquiera de los extremos son descartados.
|
|
Desplazamientos de izquierda tienen ceros desplazados a la derecha mientras que el
|
|
bit de signo es desplazado fuera a la izquierda, es decir que no se conserva el
|
|
signo de un operando.
|
|
Desplazamientos a la derecha tienen copias del bit de signo desplazado a la izquierda,
|
|
es decir que se conserva el signo de un operando.
|
|
</para>
|
|
<para>
|
|
Utilice paréntesis para garantizar la
|
|
<link linkend="language.operators.precedence">precedencia</link> deseada.
|
|
Por ejemplo, <literal>$a & $b == true</literal> evalúa
|
|
la equivalencia y luego el bit a bit, mientras que
|
|
<literal>($a & $b) == true</literal> evalúa el bit a bit y
|
|
luego la equivalencia.
|
|
</para>
|
|
<para>
|
|
Si los operandos para los operadores <literal>&</literal>, <literal>|</literal> y
|
|
<literal>^</literal> son string, la operación se realizará
|
|
con los valores ASCII de los caracteres que componen dichos string, y el
|
|
resultado será también un string. En todos los demás casos, ambos operandos serán
|
|
<link linkend="language.types.integer.casting">convertidos a valores de tipo integer</link>
|
|
y el resultado será también un integer.
|
|
</para>
|
|
<para>
|
|
Si el operando del operados <literal>~</literal> es un string, la
|
|
operación se realizará con valores los ASCII de los caracteres que componen
|
|
dicho string, y el resultado también será un string; en caso contrario, el operando y
|
|
el resultado serán tratados como valores de tipo integer.
|
|
</para>
|
|
<para>
|
|
Ambos operandos y el resultado de lo operadores <literal><<</literal> y
|
|
<literal>>></literal> siempre son tratados como valores de tipo integer.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<para>
|
|
<literallayout>
|
|
El ajuste ini error_reporting utiliza valores a nivel de bit,
|
|
lo que ofrece una demostración del mundo real de desactivar
|
|
bits. Para mostrar todos los errores, a excepción de los avisos,
|
|
las instrucciones del archivo php.ini dicen utilizar:
|
|
<userinput>E_ALL & ~E_NOTICE</userinput>
|
|
</literallayout>
|
|
</para>
|
|
<para>
|
|
<literallayout>
|
|
Esto funciona iniciando con E_ALL:
|
|
<computeroutput>00000000000000000111011111111111</computeroutput>
|
|
Luego se toma el valor de E_NOTICE ...
|
|
<computeroutput>00000000000000000000000000001000</computeroutput>
|
|
... y se invierte por medio de <literal>~</literal>:
|
|
<computeroutput>11111111111111111111111111110111</computeroutput>
|
|
Finalmente, se utiliza AND (&) para encontrar los bits que se
|
|
activaron en ambos valores:
|
|
<computeroutput>00000000000000000111011111110111</computeroutput>
|
|
</literallayout>
|
|
</para>
|
|
<para>
|
|
<literallayout>
|
|
Otra forma de lograrlo es mediante XOR (<literal>^</literal>)
|
|
para encontrar los bits que están activados en sólo el primer valor o en el otro:
|
|
<userinput>E_ALL ^ E_NOTICE</userinput>
|
|
</literallayout>
|
|
</para>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<para>
|
|
<literallayout>
|
|
error_reporting también se puede utilizar para demostrar la activación de bits.
|
|
La forma para mostrar sólo los errores y los errores recuperables es:
|
|
<userinput>E_ERROR | E_RECOVERABLE_ERROR</userinput>
|
|
</literallayout>
|
|
</para>
|
|
<para>
|
|
<literallayout>
|
|
Este proceso combina E_ERROR
|
|
<computeroutput>00000000000000000000000000000001</computeroutput>
|
|
y
|
|
<computeroutput>00000000000000000001000000000000</computeroutput>
|
|
usando el operador OR (<literal>|</literal>)
|
|
para obtener los bits activados en cualquiera de estos valores:
|
|
<computeroutput>00000000000000000001000000000001</computeroutput>
|
|
</literallayout>
|
|
</para>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Operaciones AND, OR y XOR bit a bit sobre integers</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
/*
|
|
* Ignore la sección superior,
|
|
* es sólo el formateado para hacer la salida más clara.
|
|
*/
|
|
|
|
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
|
|
. ' %3$s (%4$2d = %4$04b)' . "\n";
|
|
|
|
echo <<<EOH
|
|
--------- --------- -- ---------
|
|
resultado valor op prueba
|
|
--------- --------- -- ---------
|
|
EOH;
|
|
|
|
|
|
/*
|
|
* Aquí están los ejemplos.
|
|
*/
|
|
|
|
$values = array(0, 1, 2, 4, 8);
|
|
$test = 1 + 4;
|
|
|
|
echo "\n AND bit a bit \n";
|
|
foreach ($values as $value) {
|
|
$result = $value & $test;
|
|
printf($format, $result, $value, '&', $test);
|
|
}
|
|
|
|
echo "\n OR inclusivo bit a bit \n";
|
|
foreach ($values as $value) {
|
|
$result = $value | $test;
|
|
printf($format, $result, $value, '|', $test);
|
|
}
|
|
|
|
echo "\n OR exclusivo (XOR) bit a bit \n";
|
|
foreach ($values as $value) {
|
|
$result = $value ^ $test;
|
|
printf($format, $result, $value, '^', $test);
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
--------- --------- -- ---------
|
|
resultado valor op prueba
|
|
--------- --------- -- ---------
|
|
AND bit a bit
|
|
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
|
|
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
|
|
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
|
|
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
|
|
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)
|
|
|
|
OR inclusivo bit a bit
|
|
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
|
|
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
|
|
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
|
|
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
|
|
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)
|
|
|
|
OR exclusivo (XOR) bit a bit
|
|
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
|
|
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
|
|
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
|
|
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
|
|
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Operaciones XOR bit a bit sobre strings</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo 12 ^ 9; // Sale '5'
|
|
|
|
echo "12" ^ "9"; // Sale el caracter de retroceso (ascii 8)
|
|
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
|
|
|
|
echo "hallo" ^ "hello"; // Salen los valores ascii #0 #4 #0 #0 #0
|
|
// 'a' ^ 'e' = #4
|
|
|
|
echo 2 ^ "3"; // Sale 1
|
|
// 2 ^ ((int)"3") == 1
|
|
|
|
echo "2" ^ 3; // Sale 1
|
|
// ((int)"2") ^ 3 == 1
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Desplazamiento de bits sobre integers</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
/*
|
|
* Aquí están los ejemplos.
|
|
*/
|
|
|
|
echo "\n--- DESPLAZAMIENTO DE BITS A LA DERECHA SOBRE ENTEROS POSITIVOS ---\n";
|
|
|
|
$val = 4;
|
|
$places = 1;
|
|
$res = $val >> $places;
|
|
p($res, $val, '>>', $places, 'copia del bit de signo desplazado hacia el lado izquierdo');
|
|
|
|
$val = 4;
|
|
$places = 2;
|
|
$res = $val >> $places;
|
|
p($res, $val, '>>', $places);
|
|
|
|
$val = 4;
|
|
$places = 3;
|
|
$res = $val >> $places;
|
|
p($res, $val, '>>', $places, 'bits desplazados fuera del lado derecho');
|
|
|
|
$val = 4;
|
|
$places = 4;
|
|
$res = $val >> $places;
|
|
p($res, $val, '>>', $places, 'mismo resultado que arriba; no se puede desplazar más allá del 0');
|
|
|
|
|
|
echo "\n--- DESPLAZAMIENTO DE BITS A LA DERECHA SOBRE ENTEROS NEGATIVOS ---\n";
|
|
|
|
$val = -4;
|
|
$places = 1;
|
|
$res = $val >> $places;
|
|
p($res, $val, '>>', $places, 'copia del bit de signo desplazado al lado izquierdo');
|
|
|
|
$val = -4;
|
|
$places = 2;
|
|
$res = $val >> $places;
|
|
p($res, $val, '>>', $places, 'bits desplazados fuera del lado derecho');
|
|
|
|
$val = -4;
|
|
$places = 3;
|
|
$res = $val >> $places;
|
|
p($res, $val, '>>', $places, 'mismo resultado que arriba; no se puede desplazar más allá del -1');
|
|
|
|
|
|
echo "\n--- DESPLAZAMIENTO DE BITS A LA IZQUIERDA SOBRE ENTEROS POSITIVOS ---\n";
|
|
|
|
$val = 4;
|
|
$places = 1;
|
|
$res = $val << $places;
|
|
p($res, $val, '<<', $places, 'ceros rellenan en el lado derecho');
|
|
|
|
$val = 4;
|
|
$places = (PHP_INT_SIZE * 8) - 4;
|
|
$res = $val << $places;
|
|
p($res, $val, '<<', $places);
|
|
|
|
$val = 4;
|
|
$places = (PHP_INT_SIZE * 8) - 3;
|
|
$res = $val << $places;
|
|
p($res, $val, '<<', $places, 'bit de signo resulta desplazado fuera');
|
|
|
|
$val = 4;
|
|
$places = (PHP_INT_SIZE * 8) - 2;
|
|
$res = $val << $places;
|
|
p($res, $val, '<<', $places, 'bit de signo desplazado fuera del lado izquierdo');
|
|
|
|
|
|
echo "\n--- DESPLAZAMIENTO DE BITS A LA IZQUIERDA SOBRE ENTEROS NEGATIVOS ---\n";
|
|
|
|
$val = -4;
|
|
$places = 1;
|
|
$res = $val << $places;
|
|
p($res, $val, '<<', $places, 'ceros rellenan en el lado derecho');
|
|
|
|
$val = -4;
|
|
$places = (PHP_INT_SIZE * 8) - 3;
|
|
$res = $val << $places;
|
|
p($res, $val, '<<', $places);
|
|
|
|
$val = -4;
|
|
$places = (PHP_INT_SIZE * 8) - 2;
|
|
$res = $val << $places;
|
|
p($res, $val, '<<', $places, 'bits desplazados fuera del lado izquierdo, incluyendo el bit de signo');
|
|
|
|
|
|
/*
|
|
* Ignore this bottom section,
|
|
* it is just formatting to make output clearer.
|
|
*/
|
|
|
|
function p($res, $val, $op, $places, $note = '') {
|
|
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";
|
|
|
|
printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);
|
|
|
|
echo " Decimal:\n";
|
|
printf(" val=%d\n", $val);
|
|
printf(" res=%d\n", $res);
|
|
|
|
echo " Binary:\n";
|
|
printf(' val=' . $format, $val);
|
|
printf(' res=' . $format, $res);
|
|
|
|
if ($note) {
|
|
echo " NOTE: $note\n";
|
|
}
|
|
|
|
echo "\n";
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.32bit;
|
|
<screen>
|
|
<![CDATA[
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA DERECHA SOBRE ENTEROS POSITIVOS ---
|
|
Expression: 2 = 4 >> 1
|
|
Decimal:
|
|
val=4
|
|
res=2
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=00000000000000000000000000000010
|
|
NOTE: copia del bit de signo desplazado hacia el lado izquierdo
|
|
|
|
Expression: 1 = 4 >> 2
|
|
Decimal:
|
|
val=4
|
|
res=1
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=00000000000000000000000000000001
|
|
|
|
Expression: 0 = 4 >> 3
|
|
Decimal:
|
|
val=4
|
|
res=0
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=00000000000000000000000000000000
|
|
NOTE: bits desplazados fuera del lado derecho
|
|
|
|
Expression: 0 = 4 >> 4
|
|
Decimal:
|
|
val=4
|
|
res=0
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=00000000000000000000000000000000
|
|
NOTE: mismo resultado que arriba; no se puede desplazar más allá del 0
|
|
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA DERECHA SOBRE ENTEROS NEGATIVOS ---
|
|
Expression: -2 = -4 >> 1
|
|
Decimal:
|
|
val=-4
|
|
res=-2
|
|
Binary:
|
|
val=11111111111111111111111111111100
|
|
res=11111111111111111111111111111110
|
|
NOTE: copia del bit de signo desplazado al lado izquierdo
|
|
|
|
Expression: -1 = -4 >> 2
|
|
Decimal:
|
|
val=-4
|
|
res=-1
|
|
Binary:
|
|
val=11111111111111111111111111111100
|
|
res=11111111111111111111111111111111
|
|
NOTE: bits desplazados fuera del lado derecho
|
|
|
|
Expression: -1 = -4 >> 3
|
|
Decimal:
|
|
val=-4
|
|
res=-1
|
|
Binary:
|
|
val=11111111111111111111111111111100
|
|
res=11111111111111111111111111111111
|
|
NOTE: mismo resultado que arriba; no se puede desplazar más allá del -1
|
|
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA IZQUIERDA SOBRE ENTEROS POSITIVOS ---
|
|
Expression: 8 = 4 << 1
|
|
Decimal:
|
|
val=4
|
|
res=8
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=00000000000000000000000000001000
|
|
NOTE: ceros rellenan en el lado derecho
|
|
|
|
Expression: 1073741824 = 4 << 28
|
|
Decimal:
|
|
val=4
|
|
res=1073741824
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=01000000000000000000000000000000
|
|
|
|
Expression: -2147483648 = 4 << 29
|
|
Decimal:
|
|
val=4
|
|
res=-2147483648
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=10000000000000000000000000000000
|
|
NOTE: bit de signo resulta desplazado fuera
|
|
|
|
Expression: 0 = 4 << 30
|
|
Decimal:
|
|
val=4
|
|
res=0
|
|
Binary:
|
|
val=00000000000000000000000000000100
|
|
res=00000000000000000000000000000000
|
|
NOTE: bit de signo desplazado fuera del lado izquierdo
|
|
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA IZQUIERDA SOBRE ENTEROS NEGATIVOS ---
|
|
Expression: -8 = -4 << 1
|
|
Decimal:
|
|
val=-4
|
|
res=-8
|
|
Binary:
|
|
val=11111111111111111111111111111100
|
|
res=11111111111111111111111111111000
|
|
NOTE: ceros rellenan en el lado derecho
|
|
|
|
Expression: -2147483648 = -4 << 29
|
|
Decimal:
|
|
val=-4
|
|
res=-2147483648
|
|
Binary:
|
|
val=11111111111111111111111111111100
|
|
res=10000000000000000000000000000000
|
|
|
|
Expression: 0 = -4 << 30
|
|
Decimal:
|
|
val=-4
|
|
res=0
|
|
Binary:
|
|
val=11111111111111111111111111111100
|
|
res=00000000000000000000000000000000
|
|
NOTE: bits desplazados fuera del lado izquierdo, incluyendo el bit de signo
|
|
]]>
|
|
</screen>
|
|
&example.outputs.64bit;
|
|
<screen>
|
|
<![CDATA[
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA DERECHA SOBRE ENTEROS POSITIVOS ---
|
|
Expression: 2 = 4 >> 1
|
|
Decimal:
|
|
val=4
|
|
res=2
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=0000000000000000000000000000000000000000000000000000000000000010
|
|
NOTE: copia del bit de signo desplazado hacia el lado izquierdo
|
|
|
|
Expression: 1 = 4 >> 2
|
|
Decimal:
|
|
val=4
|
|
res=1
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=0000000000000000000000000000000000000000000000000000000000000001
|
|
|
|
Expression: 0 = 4 >> 3
|
|
Decimal:
|
|
val=4
|
|
res=0
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=0000000000000000000000000000000000000000000000000000000000000000
|
|
NOTE: bits desplazados fuera del lado derecho
|
|
|
|
Expression: 0 = 4 >> 4
|
|
Decimal:
|
|
val=4
|
|
res=0
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=0000000000000000000000000000000000000000000000000000000000000000
|
|
NOTE: mismo resultado que arriba; no se puede desplazar más allá del 0
|
|
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA DERECHA SOBRE ENTEROS NEGATIVOS ---
|
|
Expression: -2 = -4 >> 1
|
|
Decimal:
|
|
val=-4
|
|
res=-2
|
|
Binary:
|
|
val=1111111111111111111111111111111111111111111111111111111111111100
|
|
res=1111111111111111111111111111111111111111111111111111111111111110
|
|
NOTE: copia del bit de signo desplazado al lado izquierdo
|
|
|
|
Expression: -1 = -4 >> 2
|
|
Decimal:
|
|
val=-4
|
|
res=-1
|
|
Binary:
|
|
val=1111111111111111111111111111111111111111111111111111111111111100
|
|
res=1111111111111111111111111111111111111111111111111111111111111111
|
|
NOTE: bits desplazados fuera del lado derecho
|
|
|
|
Expression: -1 = -4 >> 3
|
|
Decimal:
|
|
val=-4
|
|
res=-1
|
|
Binary:
|
|
val=1111111111111111111111111111111111111111111111111111111111111100
|
|
res=1111111111111111111111111111111111111111111111111111111111111111
|
|
NOTE: mismo resultado que arriba; no se puede desplazar más allá del -1
|
|
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA IZQUIERDA SOBRE ENTEROS POSITIVOS ---
|
|
Expression: 8 = 4 << 1
|
|
Decimal:
|
|
val=4
|
|
res=8
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=0000000000000000000000000000000000000000000000000000000000001000
|
|
NOTE: ceros rellenan en el lado derecho
|
|
|
|
Expression: 4611686018427387904 = 4 << 60
|
|
Decimal:
|
|
val=4
|
|
res=4611686018427387904
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=0100000000000000000000000000000000000000000000000000000000000000
|
|
|
|
Expression: -9223372036854775808 = 4 << 61
|
|
Decimal:
|
|
val=4
|
|
res=-9223372036854775808
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=1000000000000000000000000000000000000000000000000000000000000000
|
|
NOTE: bit de signo resulta desplazado fuera
|
|
|
|
Expression: 0 = 4 << 62
|
|
Decimal:
|
|
val=4
|
|
res=0
|
|
Binary:
|
|
val=0000000000000000000000000000000000000000000000000000000000000100
|
|
res=0000000000000000000000000000000000000000000000000000000000000000
|
|
NOTE: bit de signo desplazado fuera del lado izquierdo
|
|
|
|
|
|
--- DESPLAZAMIENTO DE BITS A LA IZQUIERDA SOBRE ENTEROS NEGATIVOS ---
|
|
Expression: -8 = -4 << 1
|
|
Decimal:
|
|
val=-4
|
|
res=-8
|
|
Binary:
|
|
val=1111111111111111111111111111111111111111111111111111111111111100
|
|
res=1111111111111111111111111111111111111111111111111111111111111000
|
|
NOTE: ceros rellenan en el lado derecho
|
|
|
|
Expression: -9223372036854775808 = -4 << 61
|
|
Decimal:
|
|
val=-4
|
|
res=-9223372036854775808
|
|
Binary:
|
|
val=1111111111111111111111111111111111111111111111111111111111111100
|
|
res=1000000000000000000000000000000000000000000000000000000000000000
|
|
|
|
Expression: 0 = -4 << 62
|
|
Decimal:
|
|
val=-4
|
|
res=0
|
|
Binary:
|
|
val=1111111111111111111111111111111111111111111111111111111111111100
|
|
res=0000000000000000000000000000000000000000000000000000000000000000
|
|
NOTE: bits desplazados fuera del lado izquierdo, incluyendo el bit de signo
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
Desplazar un integer por valores mayores o iguales al ancho del tipo long integer
|
|
del sistema resultará en un comportamiento indefinido. En otras palabras, no desplace
|
|
más de 31 bit en sistemas de 32 bit, y no desplace más de 63 bit en sistemas
|
|
de 64 bit.
|
|
</para>
|
|
<para>
|
|
Use funciones de la extensión <link linkend="book.gmp">gmp</link> para
|
|
manipular a nivel de bit números mayores que <literal>PHP_INT_MAX</literal>.
|
|
</para>
|
|
</warning>
|
|
<para>
|
|
Ver también
|
|
<function>pack</function>,
|
|
<function>unpack</function>,
|
|
<function>gmp_and</function>,
|
|
<function>gmp_or</function>,
|
|
<function>gmp_xor</function>,
|
|
<function>gmp_testbit</function>,
|
|
<function>gmp_clrbit</function>
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.comparison">
|
|
<title>Operadores de comparación</title>
|
|
<simpara>
|
|
Los operadores de comparación, como su nombre lo indica, permiten comparar
|
|
dos valores. Puede también estar interesado en ver
|
|
<link linkend="types.comparisons">las tablas de comparación de tipos</link>,
|
|
ya que muestran ejemplos de las varias comparaciones relacionadas con tipos.
|
|
</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 de la manipulación de tipos.</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> no es igual a <varname>$b</varname> después de la manipulación de tipos.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <> $b</entry>
|
|
<entry>Diferente</entry>
|
|
<entry>&true; si <varname>$a</varname> no es igual a <varname>$b</varname> después de la manipulación de tipos.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a !== $b</entry>
|
|
<entry>No idéntico</entry>
|
|
<entry>
|
|
&true; si <varname>$a</varname> no es igual a <varname>$b</varname>, o 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 que</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 que</entry>
|
|
<entry>&true; si <varname>$a</varname> es menor o igual que <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a >= $b</entry>
|
|
<entry>Mayor o igual que</entry>
|
|
<entry>&true; si <varname>$a</varname> es mayor o igual que <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <=> $b</entry>
|
|
<entry>Nave espacial</entry>
|
|
<entry>
|
|
Un <type>integer</type> menor que, igual a, o mayor que cero cuando
|
|
<varname>$a</varname> es respectivamente menor que, igual a, o mayor
|
|
que <varname>$b</varname>. Disponible a partir de PHP 7.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a ?? $b ?? $c</entry>
|
|
<entry>Fusión de null</entry>
|
|
<entry>
|
|
El primer operando de izquierda a derecha que exista y no sea &null;.
|
|
&null; si no hay valores definidos y no son &null;. Disponible a partir de PHP 7.
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
Si se compara un número con un string o la comparación implica strings
|
|
numéricos, entonces cada string es
|
|
<link linkend="language.types.string.conversion">convertido en un número</link>
|
|
y la comparación realizada numéricamente. Estas reglas también se aplican a la sentencia
|
|
<link linkend="control-structures.switch">switch</link>. La
|
|
conversión de tipo no tiene lugar cuando la comparación es === o !== ya que
|
|
esto involucra comparar el tipo así como el valor.
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
var_dump(0 == "a"); // 0 == 0 -> true
|
|
var_dump("1" == "01"); // 1 == 1 -> true
|
|
var_dump("10" == "1e1"); // 10 == 10 -> true
|
|
var_dump(100 == "1e2"); // 100 == 100 -> true
|
|
|
|
switch ("a") {
|
|
case 0:
|
|
echo "0";
|
|
break;
|
|
case "a": // nunca alcanzado debido a que "a" ya ha coincidido con 0
|
|
echo "a";
|
|
break;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Integers
|
|
echo 1 <=> 1; // 0
|
|
echo 1 <=> 2; // -1
|
|
echo 2 <=> 1; // 1
|
|
|
|
// Floats
|
|
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
|
|
|
|
// Objects
|
|
$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
|
|
|
|
// only values are compared
|
|
$a = (object) ["a" => "b"];
|
|
$b = (object) ["b" => "b"];
|
|
echo $a <=> $b; // 1
|
|
|
|
?>
|
|
]]>
|
|
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>
|
|
Para varios tipos, la comparación se realiza de acuerdo a la siguiente
|
|
tabla (en orden).
|
|
</para>
|
|
<table xml:id="language.operators.comparison.types">
|
|
<title>La comparación con varios tipos</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Tipo de operando 1</entry>
|
|
<entry>Tipo de 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>cualquiera</entry>
|
|
<entry>Convierte ambos lados a <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 propia comparación, diferentes clases
|
|
son incomparables, la misma clase - comparan propiedades en la misma forma que
|
|
los arrays (PHP 4), PHP 5 tiene su propia <link
|
|
linkend="language.oop5.object-comparison">explicación</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>string</type>, <type>resource</type> o <type>number</type></entry>
|
|
<entry><type>string</type>, <type>resource</type> o <type>number</type></entry>
|
|
<entry>Traducir las cadenas y recursos a números, matemática usual</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>array</type></entry>
|
|
<entry><type>array</type></entry>
|
|
<entry>Un array con menos elementos es menor, si una clave del operando 1 no se
|
|
encuentra en el operando 2 entonces los arrays son incomparables, de otra forma - compara
|
|
valor por valor (ver el siguiente ejemplo)</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>object</type></entry>
|
|
<entry>cualquiera</entry>
|
|
<entry><type>object</type> es siempre mayor</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>array</type></entry>
|
|
<entry>cualquiera</entry>
|
|
<entry><type>array</type> es siempre mayor</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
|
|
<para>
|
|
<example>
|
|
<title>Comparación boolean/null</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Booleanos y null son comparados siempre coomo bool
|
|
var_dump(1 == TRUE); // TRUE - same as (bool)1 == TRUE
|
|
var_dump(0 == FALSE); // TRUE - same as (bool)0 == FALSE
|
|
var_dump(100 < TRUE); // FALSE - same as (bool)100 < TRUE
|
|
var_dump(-10 < FALSE);// FALSE - same as (bool)-10 < FALSE
|
|
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 is FALSE < TRUE
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
|
|
<para>
|
|
<example>
|
|
<title>Transcripción de la comparación estándar de arrays</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Arrays son comparados de esta forma con los operadores de comparación estándar
|
|
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 null; // uncomparable
|
|
} elseif ($val < $op2[$key]) {
|
|
return -1;
|
|
} elseif ($val > $op2[$key]) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0; // $op1 == $op2
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
Ver también <function>strcasecmp</function>,
|
|
<function>strcmp</function>,
|
|
<link linkend="language.operators.array">operadores de array</link>,
|
|
y la sección del manual sobre
|
|
<link linkend="language.types">tipos</link>.
|
|
</para>
|
|
|
|
<warning>
|
|
<title>Comparación de números de punto flotante</title>
|
|
|
|
<para>
|
|
Debido a la forma en que son representados internamente los <type>float</type>s, no
|
|
se deben probar por igualdad dos <type>float</type>s.
|
|
</para>
|
|
|
|
<para>
|
|
Ver la documentación de <type>float</type> para más información.
|
|
</para>
|
|
</warning>
|
|
|
|
<sect2 xml:id="language.operators.comparison.ternary">
|
|
<title>Operador ternario</title>
|
|
<para>
|
|
Otro operador condicional es el operador "?:" (o ternario).
|
|
<example>
|
|
<title>Asignación de un valor predeterminado</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Ejemplo de uso para: Operador Ternario
|
|
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
|
|
|
|
// Lo anterior es idéntico a esta sentencia if/else
|
|
if (empty($_POST['action'])) {
|
|
$action = 'default';
|
|
} else {
|
|
$action = $_POST['action'];
|
|
}
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
La expresión <literal>(expr1) ? (expr2) : (expr3)</literal>
|
|
evalúa a <replaceable>expr2</replaceable> si
|
|
<replaceable>expr1</replaceable> se evalúa como &true; y a
|
|
<replaceable>expr3</replaceable> si
|
|
<replaceable>expr1</replaceable> se evalúa como &false;.
|
|
</para>
|
|
<para>
|
|
A partir de PHP 5.3, es posible dejar de lado la parte media del operador
|
|
ternario. La expresión <literal>expr1 ?: expr3</literal> retorna
|
|
<replaceable>expr1</replaceable> si <replaceable>expr1</replaceable>
|
|
se evalúa como &true; y <replaceable>expr3</replaceable> si es de otra manera.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Por favor note que el operador ternario es una expresión, y que
|
|
no evalúa a una variable, sino al resultado de una expresión. Esto
|
|
es importante saberlo si se desea retornar una variable por referencia.
|
|
La sentencia <literal>return $var == 42 ? $a : $b;</literal> en una
|
|
función con retorno-por-referencia no funcionará por lo que se ha mencionado y una advertencia es
|
|
generada en versiones posteriores de PHP.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Es recomendable evitar el "apilamiento" expresiones ternarias. El
|
|
comportamiento de PHP al utilizar más de un operador ternario en una única
|
|
sentencia no es evidente:
|
|
<example>
|
|
<title>Comportamiento Ternario poco obvio</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// a primera vista, lo siguiente parece tener la salida de 'true'
|
|
echo (true?'true':false?'t':'f');
|
|
|
|
// sin embargo, la salida real de lo anterior es 't'
|
|
// esto se debe a que las expresiones ternarias se evalúan de izquierda a derecha
|
|
|
|
// la siguiente es una versión más obvia del mismo código anterior
|
|
echo ((true ? 'true' : false) ? 't' : 'f');
|
|
|
|
// aquí, se puede ver que la primera expresión es evaluada como 'true', que
|
|
// a su vez se evalúa como (bool)true, retornando así la rama verdadera de la
|
|
// segunda expresión ternaria.
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
</sect2>
|
|
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.errorcontrol">
|
|
<title>Operadores de control de errores</title>
|
|
<simpara>
|
|
PHP soporta un operador de control de errores: el signo de arroba (@). Cuando
|
|
se antepone a una expresión en PHP, cualquier mensaje de error que pueden
|
|
ser generado por esa expresión será ignorado.
|
|
</simpara>
|
|
<simpara>
|
|
Si se ha establecido una función controladora de errores personalizada con
|
|
<function>set_error_handler</function> entonces todavía será
|
|
llamada, pero este controlador de errores personalizado puede (y debe) llamar a <function>error_reporting</function>
|
|
el cual devolverá 0 cuando la llamada que provocó el error fue precedida por el signo @.
|
|
</simpara>
|
|
<simpara>
|
|
Si la propiedad <link linkend="ini.track-errors"><option>track_errors</option></link>
|
|
está activada, cualquier mensaje de error generado por la expresión
|
|
será guardada en la variable
|
|
<varname>$php_errormsg</varname>.
|
|
Esta variable se sobrescribe en cada error, así que se debe comprobar antes si
|
|
se desea utilizar.
|
|
</simpara>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
/* Error intencional de archivo */
|
|
$my_file = @file ('non_existent_file') or
|
|
die ("La apertura de archivo ha fallado: el error fue '$php_errormsg'");
|
|
|
|
// esto funciona con cualquier expresión, no solo con funciones:
|
|
$value = @$cache[$key];
|
|
// no producirá una anotación si el índice $key no existe.
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
El operador @ trabaja sólo sobre
|
|
<link linkend="language.expressions">expresiones</link>. Una simple regla
|
|
de oro es: si se puede tomar el valor de algo, entonces se le puede anteponer
|
|
el operador @. Por ejemplo, puede anteponerse a variables,
|
|
a llamadas a funciones e <function>include</function>s, constantes y
|
|
así sucesivamente. No puede anteponerse a definiciones de función o clase,
|
|
ni a estructuras condicionales como <literal>if</literal> y
|
|
&foreach;, y así sucesivamente.
|
|
</simpara>
|
|
</note>
|
|
<simpara>
|
|
Ver también <function>error_reporting</function> y la sección del manual sobre
|
|
<link linkend="ref.errorfunc">funciones de Manejo de Errores y Registros</link>.
|
|
</simpara>
|
|
<warning>
|
|
<para>
|
|
En la actualidad, el operador de prefijo "@" para control de errores deshabilitará incluso
|
|
el reporte de errores en casos de fallos críticos que terminarán la ejecución del
|
|
script. Entre otras cosas, esto quiere decir que si se usa "@" para
|
|
eliminar los errores de una cierta función y ésta no se encuentra
|
|
disponible o ha sido escrita de forma incorrecta, el script se detendrá en ese punto
|
|
sin indicación de por qué.
|
|
</para>
|
|
</warning>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.execution">
|
|
<title>Operadores de ejecución</title>
|
|
<para>
|
|
PHP soporta un operador de ejecución: las comillas invertidas (``). ¡Note que
|
|
estas no son las comillas sencillas! PHP intentará ejecutar el
|
|
contenido entre las comillas invertidas como si se tratara de un comando del shell; la salida será
|
|
retornada (es decir, no será simplemente volcada como salida; puede ser
|
|
asignada a una variable). El uso del operador de comillas invertidas es idéntico
|
|
al de <function>shell_exec</function>.
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$output = `ls -al`;
|
|
echo "<pre>$output</pre>";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
El operador de comillas invertidas se deshabilita cuando &safemode; esta activado
|
|
o <function>shell_exec</function> esta desactivado.
|
|
</para>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
A diferencia de otros lenguajes, las comillas invertidas no tienen un significa especial
|
|
dentro de string entre comillas dobles.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
Vea también la sección del manual sobre <link linkend="ref.exec">funciones
|
|
de ejecución de programas</link>, <function>popen</function>
|
|
<function>proc_open</function> y
|
|
<link linkend="features.commandline">Usando PHP desde la
|
|
línea de comandos</link>.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.increment">
|
|
<title>Operadores de incremento/decremento</title>
|
|
<para>
|
|
PHP soporta operadores estilo C de pre- y post-incremento
|
|
y decremento.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Los operadores de incremento/decremento solamente afectan a números y strings.
|
|
Los arrays, objects y resources no se ven afectados.
|
|
Decrementar valores &null; tampoco tiene efecto, pero incrementarlos entonces
|
|
resulta en <literal>1</literal>.
|
|
</simpara>
|
|
</note>
|
|
<table>
|
|
<title>Operadores de incremento/decremento</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Ejemplo</entry>
|
|
<entry>Nombre</entry>
|
|
<entry>Efecto</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>++$a</entry>
|
|
<entry>Pre-incremento</entry>
|
|
<entry>Incrementa <varname>$a</varname> en uno, y luego retorna <varname>$a</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a++</entry>
|
|
<entry>Post-incremento</entry>
|
|
<entry>Retorna <varname>$a</varname>, y luego incrementa <varname>$a</varname> en uno.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>--$a</entry>
|
|
<entry>Pre-decremento</entry>
|
|
<entry>Decrementa <varname>$a</varname> en uno, luego retorna <varname>$a</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a--</entry>
|
|
<entry>Post-decremento</entry>
|
|
<entry>Retorna <varname>$a</varname>, luego decrementa <varname>$a</varname> en uno.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
Aquí hay un script simple de ejemplo:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo "<h3>Postincremento</h3>";
|
|
$a = 5;
|
|
echo "Debe ser 5: " . $a++ . "<br />\n";
|
|
echo "Debe ser 6: " . $a . "<br />\n";
|
|
|
|
echo "<h3>Preincremento</h3>";
|
|
$a = 5;
|
|
echo "Debe ser 6: " . ++$a . "<br />\n";
|
|
echo "Debe ser 6: " . $a . "<br />\n";
|
|
|
|
echo "<h3>Postdecremento</h3>";
|
|
$a = 5;
|
|
echo "Debe ser 5: " . $a-- . "<br />\n";
|
|
echo "Debe ser 4: " . $a . "<br />\n";
|
|
|
|
echo "<h3>Predecremento</h3>";
|
|
$a = 5;
|
|
echo "Debe ser 4: " . --$a . "<br />\n";
|
|
echo "Debe ser 4: " . $a . "<br />\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
PHP sigue la convención de Perl cuando trabaja con operaciones aritméticas
|
|
sobre variables de caracteres y no la de C. Por ejemplo, en PHP y Perl
|
|
<literal>$a = 'Z'; $a++;</literal> convierte <literal>$a</literal> en <literal>'AA'</literal>, mientras que en C
|
|
<literal>a = 'Z'; a++;</literal> convierte <literal>a</literal> en <literal>'['</literal>
|
|
(el valor ASCII de <literal>'Z'</literal> es 90, el valor ASCII de <literal>'['</literal> es 91).
|
|
Nótese que las variables de caracteres pueden ser incrementadas pero no decrementadas y
|
|
aun así sólo caracteres y dígitos de ASCII puro (a-z, A-Z y 0-9) están soportados.
|
|
Incrementar o decrementar otras variables de caracteres no tiene efecto, el
|
|
string original no se modifica.
|
|
<example>
|
|
<title>Operaciones aritméticas sobre variables de caracteres</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo '== Letras ==' . PHP_EOL;
|
|
$s = 'W';
|
|
for ($n=0; $n<6; $n++) {
|
|
echo ++$s . PHP_EOL;
|
|
}
|
|
// Los caracteres de dígitos tienen un comportamiento diferente
|
|
echo '== Dígitos ==' . PHP_EOL;
|
|
$d = 'A8';
|
|
for ($n=0; $n<6; $n++) {
|
|
echo ++$d . PHP_EOL;
|
|
}
|
|
$d = 'A08';
|
|
for ($n=0; $n<6; $n++) {
|
|
echo ++$d . PHP_EOL;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
== Letras ==
|
|
X
|
|
Y
|
|
Z
|
|
AA
|
|
AB
|
|
AC
|
|
== Dígitos ==
|
|
A9
|
|
B0
|
|
B1
|
|
B2
|
|
B3
|
|
B4
|
|
A09
|
|
A10
|
|
A11
|
|
A12
|
|
A13
|
|
A14
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Incrementar o decrementar booleanos no tiene efecto.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.logical">
|
|
<title>Operadores lógicos</title>
|
|
|
|
<table>
|
|
<title>Operadores lógicos</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Ejemplo</entry>
|
|
<entry>Nombre</entry>
|
|
<entry>Resultado</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>$a and $b</entry>
|
|
<entry>And (y)</entry>
|
|
<entry>&true; si tanto <varname>$a</varname> como <varname>$b</varname> son &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a or $b</entry>
|
|
<entry>Or (o inclusivo)</entry>
|
|
<entry>&true; si cualquiera de <varname>$a</varname> o <varname>$b</varname> es &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a xor $b</entry>
|
|
<entry>Xor (o exclusivo)</entry>
|
|
<entry>&true; si <varname>$a</varname> o <varname>$b</varname> es &true;, pero no ambos.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>! $a</entry>
|
|
<entry>Not (no)</entry>
|
|
<entry>&true; si <varname>$a</varname> no es &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a && $b</entry>
|
|
<entry>And (y)</entry>
|
|
<entry>&true; si tanto <varname>$a</varname> como <varname>$b</varname> son &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a || $b</entry>
|
|
<entry>Or (o inclusivo)</entry>
|
|
<entry>&true; si cualquiera de <varname>$a</varname> o <varname>$b</varname> es &true;.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<simpara>
|
|
La razón para tener las dos variaciones diferentes de los operadores
|
|
"and" y "or" es que ellos operan con precedencias diferentes. (Ver
|
|
<link linkend="language.operators.precedence">Precedencia
|
|
de operadores</link>.)
|
|
</simpara>
|
|
<example>
|
|
<title>Los operadores lógicos ilustrados</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// --------------------
|
|
// foo() nunca será llamado ya que los operadores están en cortocircuito
|
|
|
|
$a = (false && foo());
|
|
$b = (true || foo());
|
|
$c = (false and foo());
|
|
$d = (true or foo());
|
|
|
|
// --------------------
|
|
// "||" tiene una precedencia mayor que "or"
|
|
|
|
// El resultado de la expresión (false || true) es asignado a $e
|
|
// Actúa como: ($e = (false || true))
|
|
$e = false || true;
|
|
|
|
// La constante false es asignada a $f antes de que suceda la operación "or"
|
|
// Actúa como: (($f = false) or true)
|
|
$f = false or true;
|
|
|
|
var_dump($e, $f);
|
|
|
|
// --------------------
|
|
// "&&" tiene una precedencia mayor que "and"
|
|
|
|
// El resultado de la expresión (true && false) es asignado a $g
|
|
// Actúa como: ($g = (true && false))
|
|
$g = true && false;
|
|
|
|
// La constante true es asignada a $h antes de que suceda la operación "and"
|
|
// Actúa como: (($h = true) and false)
|
|
$h = true and false;
|
|
|
|
var_dump($g, $h);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs.similar;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(false)
|
|
bool(false)
|
|
bool(true)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.string">
|
|
<title>Operadores para strings</title>
|
|
<simpara>
|
|
Existen dos operadores para datos tipo <type>string</type>. El primero es el
|
|
operador de concatenación ('.'), el cual retorna el resultado de concatenar sus
|
|
argumentos derecho e izquierdo. El segundo es el operador de asignación sobre
|
|
concatenación ('<literal>.=</literal>'), el cual añade el argumento del lado derecho al
|
|
argumento en el lado izquierdo. Por favor consulte <link
|
|
linkend="language.operators.assignment">Operadores de
|
|
asignación</link> para más información.
|
|
</simpara>
|
|
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = "Hello ";
|
|
$b = $a . "World!"; // ahora $b contiene "Hello World!"
|
|
|
|
$a = "Hello ";
|
|
$a .= "World!"; // ahora $a contiene "Hello World!"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Ver también las secciones del manual sobre el
|
|
<link linkend="language.types.string">tipo string</link> y las
|
|
<link linkend="ref.strings">funciones de strings</link>.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="language.operators.array">
|
|
<title>Operadores para arrays</title>
|
|
<table>
|
|
<title>Operadores para arrays</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Ejemplo</entry>
|
|
<entry>Nombre</entry>
|
|
<entry>Resultado</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>$a + $b</entry>
|
|
<entry>Unión</entry>
|
|
<entry>Unión de <varname>$a</varname> y <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a == $b</entry>
|
|
<entry>Igualdad</entry>
|
|
<entry>&true; si <varname>$a</varname> i <varname>$b</varname> tienen las mismas parejas clave/valor.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a === $b</entry>
|
|
<entry>Identidad</entry>
|
|
<entry>&true; si <varname>$a</varname> y <varname>$b</varname> tienen las mismas parejas clave/valor en el mismo
|
|
orden y de los mismos tipos.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a != $b</entry>
|
|
<entry>Desigualdad</entry>
|
|
<entry>&true; si <varname>$a</varname> no es igual a <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <> $b</entry>
|
|
<entry>Desigualdad</entry>
|
|
<entry>&true; si <varname>$a</varname> no es igual a <varname>$b</varname>.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a !== $b</entry>
|
|
<entry>No-identidad</entry>
|
|
<entry>&true; si <varname>$a</varname> no es idéntica a <varname>$b</varname>.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
El operador <literal>+</literal> devuelve el array del lado derecho añadido
|
|
al array del lado izquierdo; para las claves que existan en ambos arrays, serán utilizados
|
|
los elementos del array de la izquierda y serán ignorados los elementos correspondientes del
|
|
array de la derecha.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = array("a" => "apple", "b" => "banana");
|
|
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
|
|
|
|
$c = $a + $b; // Unión de $a y $b
|
|
echo "Unión de \$a y \$b: \n";
|
|
var_dump($c);
|
|
|
|
$c = $b + $a; // Unión de $b y $a
|
|
echo "Unión de \$b y \$a: \n";
|
|
var_dump($c);
|
|
|
|
$a += $b; // Unión de $a += $b es $a y $b
|
|
echo "Unión de \$a += \$b: \n";
|
|
var_dump($a);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
Cuando sea ejecutado, este script producirá la siguiente salida:
|
|
<screen role="php">
|
|
<![CDATA[
|
|
Unión de $a y $b:
|
|
array(3) {
|
|
["a"]=>
|
|
string(5) "apple"
|
|
["b"]=>
|
|
string(6) "banana"
|
|
["c"]=>
|
|
string(6) "cherry"
|
|
}
|
|
Unión de $b y $a:
|
|
array(3) {
|
|
["a"]=>
|
|
string(4) "pear"
|
|
["b"]=>
|
|
string(10) "strawberry"
|
|
["c"]=>
|
|
string(6) "cherry"
|
|
}
|
|
Unión de $a += $b:
|
|
array(3) {
|
|
'a' =>
|
|
string(5) "apple"
|
|
'b' =>
|
|
string(6) "banana"
|
|
'c' =>
|
|
string(6) "cherry"
|
|
}
|
|
]]>
|
|
</screen>
|
|
</para>
|
|
<para>
|
|
Los elementos de los arrays son iguales para la comparación si éstos tienen la
|
|
misma clave y valor.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Comparando arrays</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = array("apple", "banana");
|
|
$b = array(1 => "banana", "0" => "apple");
|
|
|
|
var_dump($a == $b); // bool(true)
|
|
var_dump($a === $b); // bool(false)
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Ver también las secciones del manual sobre el
|
|
<link linkend="language.types.array">tipo array</link> y
|
|
<link linkend="ref.array">funciones de arrays</link>.
|
|
</para>
|
|
</sect1>
|
|
<sect1 xml:id="language.operators.type">
|
|
<title>Operadores de tipo</title>
|
|
<para>
|
|
<literal>instanceof</literal> se utiliza para determinar si una variable de PHP
|
|
es un objeto instanciado de una cierta
|
|
<link linkend="language.oop5.basic.class">clase</link>:
|
|
<example>
|
|
<title>Utilizando <literal>instanceof</literal> con clases</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class MyClass
|
|
{
|
|
}
|
|
|
|
class NotMyClass
|
|
{
|
|
}
|
|
$a = new MyClass;
|
|
|
|
var_dump($a instanceof MyClass);
|
|
var_dump($a instanceof NotMyClass);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(false)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
<literal>instanceof</literal> también se puede utilizar para determinar si una variable
|
|
es un objeto instanciado de una clase que hereda de una clase padre:
|
|
<example>
|
|
<title>Utilizando <literal>instanceof</literal> con clases heredadas</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class ParentClass
|
|
{
|
|
}
|
|
|
|
class MyClass extends ParentClass
|
|
{
|
|
}
|
|
|
|
$a = new MyClass;
|
|
|
|
var_dump($a instanceof MyClass);
|
|
var_dump($a instanceof ParentClass);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Para comprobar si un objeto <emphasis>no</emphasis> es una instancia de una clase, se
|
|
puede usar el <link linkend="language.operators.logical">operador lógico
|
|
<literal>not</literal></link>.
|
|
<example>
|
|
<title>Utilizando <literal>instanceof</literal> para verificar si un objeto <emphasis>no</emphasis> es una
|
|
instancia de una clase</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class MyClass
|
|
{
|
|
}
|
|
|
|
$a = new MyClass;
|
|
var_dump(!($a instanceof stdClass));
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Finalmente, <literal>instanceof</literal> también se puede utilizar para determinar si
|
|
una variable es un objeto instanciado de una clase que implementa una
|
|
<link linkend="language.oop5.interfaces">interface</link>:
|
|
<example>
|
|
<title>Utilizando <literal>instanceof</literal> para la clase</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
interface MyInterface
|
|
{
|
|
}
|
|
|
|
class MyClass implements MyInterface
|
|
{
|
|
}
|
|
|
|
$a = new MyClass;
|
|
|
|
var_dump($a instanceof MyClass);
|
|
var_dump($a instanceof MyInterface);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Aunque <literal>instanceof</literal> se utiliza generalmente con un nombre de clase literal,
|
|
también puede ser utilizado con otro objeto o una variable string:
|
|
<example>
|
|
<title>Utilizando <literal>instanceof</literal> con otras variables</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
interface MyInterface
|
|
{
|
|
}
|
|
|
|
class MyClass implements MyInterface
|
|
{
|
|
}
|
|
|
|
$a = new MyClass;
|
|
$b = new MyClass;
|
|
$c = 'MyClass';
|
|
$d = 'NotMyClass';
|
|
|
|
var_dump($a instanceof $b); // $b is an object of class MyClass
|
|
var_dump($a instanceof $c); // $c is a string 'MyClass'
|
|
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
bool(false)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
instanceof no lanza ningún error si la variable que está siendo comprobada no es
|
|
un objeto, simplemente devuelve &false;. Las constantes, sin embargo, no está permitidas.
|
|
<example>
|
|
<title>Usar <literal>instanceof</literal> para comprobar otras variables</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = 1;
|
|
$b = NULL;
|
|
$c = imagecreate(5, 5);
|
|
var_dump($a instanceof stdClass); // $a es un entero
|
|
var_dump($b instanceof stdClass); // $b es NULL
|
|
var_dump($c instanceof stdClass); // $c es un recurso
|
|
var_dump(FALSE instanceof stdClass);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(false)
|
|
bool(false)
|
|
bool(false)
|
|
PHP Fatal error: instanceof expects an object instance, constant given
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Hay algunas trampas a tener en cuenta. Antes de versión de PHP 5.1.0,
|
|
<literal>instanceof</literal> llamaría a <function>__autoload</function>
|
|
si el nombre de clase no existía. Además, si la clase no estaba cargada,
|
|
un error fatal ocurriría. Esto se puede solucionar mediante una referencia
|
|
de clase dinámica o una variable string que contenga el nombre de la clase:
|
|
<example>
|
|
<title>Evitando búsquedas del nombre de clase y errores fatales con <literal>instanceof</literal> en PHP 5.0</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$d = 'NotMyClass';
|
|
var_dump($a instanceof $d); // aquí no hay error fatal
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(false)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<simpara>
|
|
El operador <literal>instanceof</literal> fue introducido en PHP 5.
|
|
Antes de esta época se utilizaba <function>is_a</function>, pero
|
|
desde entonces <function>is_a</function> se ha quedado obsoleto en favor de
|
|
<literal>instanceof</literal>. Tenga en cuenta que a partir de PHP 5.3.0,
|
|
<function>is_a</function> ya no está obsoleto.
|
|
</simpara>
|
|
<para>
|
|
Ver también <function>get_class</function> y
|
|
<function>is_a</function>.
|
|
</para>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|