Cadenas de caracteres (Strings)
Un string, o cadena, es una serie de caracteres donde cada carácter es
lo mismo que un byte. Esto significa que PHP solo admite un conjunto de 256 caracteres,
y de ahí que no ofrezca soporte nativo para Unicode. Véanse los
detalles del tipo
string.
Nota:
Un string puede llegar a alcanzar hasta 2 GB de tamaño (2147483647 bytes máximo).
Sintaxis
Un literal de tipo string se puede especificar de cuatro formas diferentes:
Entrecomillado simple
La manera más sencilla de especificar un string es delimitarlo con comillas
simples (el carácter '
).
Para especificar una comilla simple literal, se ha de escapar con una barra invertida
(\
). Para especificar una barra invertida literal, se duplica
(\\
). Todas las demás instancias de barras invertidas serán tratadas
como una barra invertida literal: esto significa que otras secuencias de escape que
podrían utilizarse, tales como \r
o \n
,
serán mostradas literalmente tal y como se especifican, en lugar de tener cualquier otro
significado especial.
Nota:
A diferencia de las sintaxis de entrecomillado doble
y heredoc, las
variables y las sentencias de escape
para caracteres especiales no se expandirán cuando estén
incluidas dentro de un string entre comillas simples.
Entrecomillado doble
Si un string está delimitado con comillas dobles ("), PHP
interpretará las siguientes secuencias de escape como caracteres especiales:
Caracteres escapados
Secuencia |
Significado |
\n |
avance de línea (LF o 0x0A (10) en ASCII) |
\r |
retorno de carro (CR o 0x0D (13) en ASCII) |
\t |
tabulador horizontal (HT o 0x09 (9) en ASCII) |
\v |
tabulador vertical (VT o 0x0B (11) en ASCII) (desde PHP 5.2.5) |
\e |
escape (ESC o 0x1B (27) en ASCII) (desde PHP 5.4.4) |
\f |
avance de página (FF o 0x0C (12) en ASCII) (desde PHP 5.2.5) |
\\ |
barra invertida |
\$ |
signo de dólar |
\" |
comillas dobles |
\[0-7]{1,3} |
la secuencia de caracteres que coincida con la expresión regular
es un carácter en notación octal, que silenciosamente desborda para encajar en un byte
(p.ej. "\400" === "\000")
|
\x[0-9A-Fa-f]{1,2} |
la secuencia de caracteres que coincida con la expresión regular
es un carácter en notación hexadecimal
|
\u{[0-9A-Fa-f]+} |
la secuencia de caracteres que coincida con la expresión regular es un
punto de código de Unicode, la cual será imprimida al string como dicha
representación UTF-8 del punto de código (añadido en PHP 7.0.0)
|
Al igual que en el entrecomillado simple de un string, escapar cualquier
otro carácter puede dar lugar a que se muestre también la barra invertida. Antes de
PHP 5.1.1, no se mostraba la barra invertida de \{$var}
.
La característica más importante del entrecomillado doble de un string
es el hecho de que se expanden los nombres de las variables. Consulte el
análisis de string
para más detalles.
Heredoc
Una tercera forma de delimitar un string es mediante la sintaxis heredoc:
<<<
. Después de este operador, se deberá proporcionar un
identificador y justo después una nueva línea. A continuación va el propio string,
y para cerrar la notación se pone el mismo identificador.
El identificador de cierre debe empezar en la primera columna
de la nueva línea. Asimismo, el identificador debe seguir las mismas reglas de
nomenclatura de las etiquetas en PHP: debe contener solo caracteres alfanuméricos y
guiones bajos, y debe empezar con un carácter alfabético o un guión bajo.
Advertencia
Es muy importante señalar que la línea con el identificador de cierre no debe
contener ningún otro carácter, excepto un punto y coma (;
).
Esto, en especial, significa que el identificador
no debe estar sangrado, y que no debe existir ningún espacio
ni tabulación antes o después del punto y coma. Es muy importante observar que
el primer carácter antes del identificador de cierre debe ser un salto de línea
definido por el sistema operativo local. Este es \n
en
los sistemas UNIX, incluyendo Mac OS X. Al delimitador de cierre le ha de seguir
tambíen una nueva línea.
Si se rompe esta regla y el identificador de cierre no está "limpio", no será
considerado como un identificador de cierre, por lo que PHP continuará buscando
uno. Si no se encuentra ningún identificador de cierre apropiado antes del final
del fichero, se producirá un error de análisis en la última línea.
No se puede emplear Heredoc para inicializar las propiedades de una clase. Desde
PHP 5.3, esta limitación es válida solamente para un heredoc que contengan variables.
Ejemplo #1 Ejemplo no válido
<?php
class foo {
public $bar = <<<EOT
bar
EOT;
}
?>
El texto heredoc se comporta como un string entre comillas dobles, pero
sin tener comillas dobles. Esto significa que no es necesario escapar las comillas en
un heredoc, aunque se puede seguir empleando los códigos de escape indicados arriba.
Pese a que las variables son expandidas, se debe tener el mismo cuidado al expresar variables
complejas en un heredoc que en un string.
Ejemplo #2 Ejemplo de entrecomillado de string en Heredoc
<?php
$str = <<<EOD
Ejemplo de una cadena
expandida en varias líneas
empleando la sintaxis heredoc.
EOD;
/* Un ejemplo más complejo con variables. */
class foo
{
var $foo;
var $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$nombre = 'MiNombre';
echo <<<EOT
Mi nombre es "$nombre". Estoy escribiendo un poco de $foo->foo.
Ahora, estoy escribiendo un poco de {$foo->bar[1]}.
Esto debería mostrar una 'A' mayúscula: \x41
EOT;
?>
El resultado del ejemplo sería:
Mi nombre es "MiNombre". Estoy escribiendo un poco de Foo.
Ahora, estoy escribiendo un poco de Bar2.
Esto debería mostrar una 'A' mayúscula: A
También se puede emplear la sintaxis Heredoc para pasar datos como
argumentos de una función:
Ejemplo #3 Ejemplo de Heredoc en argumentos
<?php
var_dump(array(<<<EOD
foobar!
EOD
));
?>
Desde PHP 5.3.0, es posible inicializar variables estáticas y propiedades/constantes
de clase mediante la sintaxis Heredoc:
Ejemplo #4 Usar Heredoc para inicializar valores estáticos
<?php
// Variables estáticas
function foo()
{
static $bar = <<<LABEL
Nada aquí...
LABEL;
}
// Propiedades/constantes de clase
class foo
{
const BAR = <<<FOOBAR
Ejemplo de constante
FOOBAR;
public $baz = <<<FOOBAR
Ejemplo de propiedad
FOOBAR;
}
?>
PHP 5.3.0 también introdujo la posibilidad de entrecomillar el identificador
de apertura en Heredoc:
Ejemplo #5 Emplear comillas dobles en Heredoc
<?php
echo <<<"FOOBAR"
¡Hola Mundo!
FOOBAR;
?>
Nowdoc
Nowdoc es a los string con comillas simples lo mismo que Heredoc lo es a los string con
comillas dobles. Un nowdoc se especifica de forma análoga a un heredoc, pero
no se realiza ningún análisis dentro del nowdoc. La construcción
es ideal para embeber código de PHP o grandes fragmentos de texto sin necesidad de
escaparlos. Comparte algunas características comunes con la construcción
<![CDATA[ ]]>
de SGML, donde se declara un bloque de
texto que no se analiza.
Un nowdoc se identifica con la misma secuencia empleada para heredoc,
<<<
, pero el identificador que le sigue está delimitado con
comillas simples, p.ej., <<<'EOT'
. Todas las reglas
para los identificadores de heredoc también son aplicables a los identificadores de
nowdoc, especialmente aquellas que se refieren al empleo del identificador de cierre.
Ejemplo #6 Ejemplo de entrecomillado de string de Nowdoc
<?php
$str = <<<'EOD'
Ejemplo de un string
expandido en varias líneas
empleando la sintaxis nowdoc.
EOD;
/* Un ejemplo más complejo con variables. */
class foo
{
public $foo;
public $bar;
function foo()
{
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$nombre = 'MiNombre';
echo <<<'EOT'
Mi nombre es "$nombre". Estoy escribiendo un poco de $foo->foo.
Ahora, estoy escribiendo un poco de {$foo->bar[1]}.
Esto debería mostrar una 'A' mayúscula: \x41
EOT;
?>
El resultado del ejemplo sería:
Mi nombre es "$nombre". Estoy escribiendo un poco de $foo->foo.
Ahora, estoy escribiendo un poco de {$foo->bar[1]}.
Esto debería mostrar una 'A' mayúscula: \x41
Ejemplo #7 Ejemplo de datos estáticos
<?php
class foo {
public $bar = <<<'EOT'
bar
EOT;
}
?>
Nota:
El soporte para Nowdoc se añadió en PHP 5.3.0.
Análisis de variables
Cuando un string es especificado mediante comillas dobles o mediante heredoc,
las variables que haya dentro de dicho string se analizarán.
Existen dos tipos de sintaxis: una
simple y otra
compleja.
La sintaxis simple es la más empleada y práctica. Proporciona una forma de embeber
una variable, un valor de un array o una propiedad de un object
dentro de un string con el mínimo esfuerzo.
La sintaxis compleja puede ser reconocida por las llaves
que delimitan la expresión.
Sintaxis simple
Si se encuentra un signo de dólar ($
), el analizador tomará
el mayor número de símbolos para formar un nombre de variable válido.
Delimitar el nombre de la variable con llaves permite especificar explícitamente
el final del nombre.
De forma parecida, se puede analizar el índice de un array o la
propiedad de un object. Con los índices de los arrays, el corchete
de cierre (]
) marca el final del índice. La misma regla se
puede aplicar a las propiedades de los objetos y a las variables simples.
Ejemplo #8 Ejemplo de sintaxis simple
<?php
$jugos = array("manzana", "naranja", "koolaid1" => "púrpura");
echo "Él tomó algo de jugo de $jugos[0].".PHP_EOL;
echo "Él tomó algo de jugo de $jugos[1].".PHP_EOL;
echo "Él tomó algo de jugo $jugos[koolaid1].".PHP_EOL;
class persona {
public $john = "John Smith";
public $jane = "Jane Smith";
public $robert = "Robert Paulsen";
public $smith = "Smith";
}
$persona = new persona();
echo "$persona->john tomó algo de jugo de $jugos[0].".PHP_EOL;
echo "$persona->john entonces dijo hola a $persona->jane.".PHP_EOL;
echo "La esposa de $persona->john saludó a $persona->robert.".PHP_EOL;
echo "$persona->robert saludó a los dos $persona->smiths."; // No funcionará
?>
El resultado del ejemplo sería:
Él tomó algo de jugo de manzana.
Él tomó algo de jugo de naranja.
Él tomó algo de jugo púrpura.
John Smith tomó algo de jugo de manzana.
John Smith entonces dijo hola a Jane Smith.
La esposa de John Smith saludó a Robert Paulsen.
Robert Paulsen saludó a los dos .
Para casos más complejos se debe emplear la sintaxis compleja.
Sintaxis compleja (llaves)
Esta sintaxis no se llama compleja porque sea compleja, sino porque
permite el empleo de expresiones complejas.
Cualquier variable escalar, elemento de array o propiedad de objeto con una
representación de tipo string puede ser incluido a través de esta sintaxis.
Simplemente se escribe la expresión del mismo modo en que aparecería por fuera del
string, y delimitándola con {
y
}
. Dado que {
no puede ser escapado, esta
sintaxis será reconocida únicamente cuando el $
siga
inmediatamente al {
. Utilice {\$
para obtener un
{$
literal. Algunos ejemplos para que quede más claro:
Con esta sintaxis, también es posible acceder a las propiedades de una
clase empleando variables dentro de un string.
Nota:
Las funciones, llamadas a métodos, variables de clase estáticas y constantes de
clases dentro de {$}
funcionan desde PHP 5.
Sin embargo, el valor accedido puede ser interpretado como el nombre
de la variable en el ámbito en el que está definido el string. El empleo
de simples llaves ({}
) no servirá para acceder
al valor devuelto por las funciones o métodos, o los valores de las
constantes de clase o variables de clase estáticas.
Acceso a string y modificacion por caracteres
Se puede acceder y modificar los caracteres dentro de un string
especificando el índice de base cero del carácter deseado después del
string empleando los corchetes de array, como en
$str[42]. Piense en un string como un
array de caracteres, en este caso. Las funciones
substr() y substr_replace()
pueden ser empleadas para extraer o reemplazar más de un carácter.
Nota:
También se puede acceder a un string utilizando llaves, como en
$str{42}, con el mismo propósito.
Advertencia
Escribir en un índice fuera del rango rellenará el string con espacios.
Los tipos que no sean integer son convertidos a integer.
Los índices ilegales emiten un error de nivel E_NOTICE
.
Los índices negativos emiten un error de nivel E_NOTICE
en la escritura, aunque se
lea un string vacío. Sólo se emplea el primer carácter de un string asignado.
La asignación de un string vacío asigna un byte NULL.
Advertencia
Internamente, los string de PHP son arrays de bytes. Por tanto, acceder o
modificar un string utilizando los corchetes de array no es seguro con caracteres
multibyte, dado que sólo se realiza con los string de codificaciones monobyte,
como ISO-8859-1.
Ejemplo #9 Algunos ejemplos de string
<?php
// Obtener el primer carácter de un string
$str = 'Esto es una prueba.';
$primero = $str[0];
// Obtener el tercer carácter de un string
$tercero = $str[2];
// Obtener el último carácter de un string
$str = 'Esto sigue siendo una prueba.';
$último = $str[strlen($str)-1];
// Modificar el último carácter de un string
$str = 'Mira el mar';
$str[strlen($str)-1] = 'l';
?>
A partir de PHP 5.4, los índices de string tienen que ser de tipo integer o integer en forma de string, si no, se emitirá
una advertencia. Anteriormente, un índice como "foo"
era convertido de manera silenciosa a 0
.
Ejemplo #10 Diferencias entre PHP 5.3 y PHP 5.4
<?php
$str = 'abc';
var_dump($str['1']);
var_dump(isset($str['1']));
var_dump($str['1.0']);
var_dump(isset($str['1.0']));
var_dump($str['x']);
var_dump(isset($str['x']));
var_dump($str['1x']);
var_dump(isset($str['1x']));
?>
Salida del ejemplo anterior en PHP 5.3:
string(1) "b"
bool(true)
string(1) "b"
bool(true)
string(1) "a"
bool(true)
string(1) "b"
bool(true)
Salida del ejemplo anterior en PHP 5.4:
string(1) "b"
bool(true)
Warning: Illegal string offset '1.0' in /tmp/t.php on line 7
string(1) "b"
bool(false)
Warning: Illegal string offset 'x' in /tmp/t.php on line 9
string(1) "a"
bool(false)
string(1) "b"
bool(false)
Nota:
El acceso a variables de otros tipos (sin incluir arrays u objetos
que implementen las interfaces apropiadas) utilizando []
o
{}
, silenciosamente retorna null
.
Nota:
PHP 5.5 añadió soporte para acceder a caracteres dentro de literales de
tipo string utilizando []
o {}
.
Conversión a string
Un valor puede convertirse a un string empleando el molde
(string)
o mediante la función strval().
La conversión automática a string tiene lugar en el ámbito de
una expresión donde sea necesario un string. Esto ocurre cuando se utilizan
las funciones echo o print, o cuando
se compara una variable con un string. Las secciones sobre
Tipos y
Manipulación de tipos lo
aclararán. Consulte también la función settype().
El valor true
del tipo boolean es convertido al string
"1"
. El valor false
del tipo boolean es convertido
al string ""
(el string vacío). Esto permite la conversión
en ambos sentidos entre los valores de los tipos boolean y string.
Un integer o float es convertido a un
string que representa textualmente el número (incluyendo
la parte exponencial para los float. Los números de punto flotante
pueden ser convertidos mediante la notación exponencial (4.1E+6
).
Nota:
El carácter para el punto decimal se define en el localismo del script
(categoría LC_NUMERIC). Consulte la función setlocale().
Los arrays siempre son convertidos al string
"Array"
. Debido a esto, echo y
print no pueden por sí mismos mostrar el contenido de un
array. Para ver un único elemento individualmente, utilice una construcción
como echo $arr['foo']
. Vea los consejos de más abajo para mostrar
el contenido completo.
Los object en PHP 4 siempre son convertidos al string
"Object"
. Para mostrar los valores de las propiedades de un objeto
para su depuración, lea los párrafos siguientes. Para obtener el nombre de la clase de
un objeto, emplee la función get_class(). A partir de PHP 5, se puede
emplear el método __toString cuando
sea relevante.
Un resource siempre es convertido a string con la
estructura "Resource id #1"
, donde 1
es el número de recurso asignado al resource por PHP durante
la ejecución. A pesar de que no se debe depender de la estructura exacta, debido a que
está sujeta a cambios, siempre será única para un recurso dado
dentro del tiempo de vida de un script en ejecución (es decir, una petición web o
proceso CLI), por lo que no será reutilizada. Para obtener el tipo de un resource,
emplee la función get_resource_type().
null
siempre es convertido a un string vacío.
Como se indicó anteriormente, la conversión directa de un array,
object o resource a un string no proporciona
información útil acerca del valor más allá de su tipo. Consulte las funciones
print_r() y var_dump() para ver medios
más efectivos de inspeccionar el contenido de estos tipos.
La mayoría de los valores de PHP pueden ser convertidos a un string para
su almacenamiento permanente. Este método se denomina serialización, y es realizado
mediante la función serialize(). Si el motor de PHP se construyó con
soporte para WDDX, los valores de PHP también pueden
ser serializacos como texto XML bien formado.
Conversión de string a números
Cuando un string es evaluado en un contexto numérico, el valor
resultante y el tipo se determina como se explica a continuación.
Si el string no contiene ninguno de los caracteres '.', 'e',
o 'E', y el valor numérico está entre los límites del tipo integer (tal como
está definido por PHP_INT_MAX
), el string
será evaluado como un integer. En todos los demás casos será
evaluado como un float.
El valor es dado por la parte inicial del string. Si el
string empieza con un dato numérico válido, éste será el valor
empleado. De lo contrario, el valor será 0 (cero). Un dato numérico válido es un
signo opcional, seguido de uno o más dígitos (opcionalmente puede contener un
punto decimal), seguido de un exponente opcional. El exponente es una 'e' o
'E' seguida de uno o más dígitos.
Para más información sobre esta conversión, consulte la página del manual de
Unix para a strtod(3).
Para probar cualesquiera de los ejemplos de esta sección, copie y péguelos e
incluya la siguiente línea para ver lo que está sucediendo:
No espere obtener el código de un carácter convirtiéndolo a un integer,
como ocurre en C. Emplee las funciones ord() y
chr() para convertir entre código códigos ASCII y
caracteres.
Detalles del tipo string
En PHP, los string se implementan como un array de bytes y con un número
entero que indica la longitud del búfer. No posee ninguna información sobre cómo
traducir esos bytes a caracteres, relegando esa tarea al programador.
No existe ninguna limitación sobre los valores que pueden componer un string; en
concreto, está permitido colocar bytes con valor 0
(“bytes NUL”)
en cualquier posición del string (aunque existen algunas funciones, citadas en este manual como
“no seguras a nivel binario”, que podrían rechazar estos string para aquellas
bibliotecas que ignoren los datos que siguen a un byte NUL.)
Este comportamiento del tipo string justifica que no exista un tipo de dato "byte"
en PHP – los string se encargan de esto. Las funciones que no devuelven datos de texto – por
ejemplo, cualquier dato leído a partir de un socket de red – devolverán valores
de tipo string.
Dado que PHP no obliga a utilizar ninguna condificación en particular, uno podría
preguntarse cómo se codifican los literales de tipo string. Por ejemplo, ¿es el string
"á"
equivalente a "\xE1"
(ISO-8859-1),
"\xC3\xA1"
(UTF-8, forma C),
"\x61\xCC\x81"
(UTF-8, forma D) o cualquier otra representación
posible? La respuesta es que un string será codificado en cualquiera forma en que
estuviera codificado el fichero del script. Por tanto, si un script estuviera escrito en
ISO-8859-1, el string se codificará en ISO-8859-1, etc. Sin embargo,
esto no es aplicable si está habilitado Zend Multibyte; en ese caso, el script
podría estar escrito en cualquier codificación (la cual es declarada explícitamente o
es detectada) para después convertirse a una determinada codificación interna, que será
entonces la codificación usada para los literales de tipo string.
Tenga presente que existen algunas limitaciones sobre la codificación del script (o en
la codificación interna, si Zend Multibyte estuviera habilitado); esto suele significar
que dicha codificación debería ser compatible con un superconjunto de ASCII, tal como
UTF-8 o ISO-8859-1. Por contra, las codificaciones dependientes del estado donde
se pueden utilizar los mismos valores de byte en estados de desplazamiento iniciales y no iniciales,
podrían generar problemas.
Por supuesto, para poder ser útiles, las funciones que operen con texto podrían partir de unos
supuestos sobre cómo está codificado el string. Desafortunadamente, respecto a
esto existen muchas variaciones en las funciones de PHP:
-
Algunas funciones asumen que el string está codificado con una codificación
de un único byte, por lo que no es necesario interpretar estos bytes como caracteres
específicos. Este es el caso de, por ejemplo, substr(),
strpos(), strlen() o
strcmp(). Otra forma de entender estas funciones es pensando
que operan sobre búferes de memoria, es decir, trabajan con bytes y con índices
de bytes.
-
A otras funciones se les proporciona la codificación del string, si bien es posible
que asuman una codificación predeterminada si no se proporciona ninguna.
Este es el caso de htmlentities() y la mayoría de
funciones de la extensión mbstring.
-
Otras utilizan el localismo en uso (véase setlocale()), pero
operan byte a byte. Este es el caso de strcasecmp(),
strtoupper() y ucfirst().
Esto significa que sólo se pueden usar con codificaciones de un byte, siempre y
cuando la codificación coincida con la del localismo. Por ejemplo,
strtoupper("á")
podría devolver "Á"
si el
localismo está correctamente establecido y á
está
codificado con un único byte. Si está codificado en UTF-8, no se devolverá un resultado
correcto, y el string resultante podría devolverse corrupto, en función del
localismo en uso.
-
Por último, las funciones podrán también asumir que se utiliza una codificación en particular,
usualmente UTF-8. Este es el caso de la mayoría de las funciones de la extensión
intl y de la extensión
PCRE
(en este último caso, sólo cuando se utiliza el modificador
u
).
Debido a su propósito especial, la función
utf8_decode() asume una codificación UTF-8, mientras que la
función utf8_encode() asume una codificación ISO-8859-1.
En resumen, para escribir programas de forma correcta usando Unicode
hay que evitar cuidadosamente las funciones que puedan fallar y que muy probablemente
corrompan los datos, y utilizar en su lugar las funciones que se comporten de forma
correcta, generalmente las de las extensiones intl y
mbstring.
Sin embargo, el uso de funciones que pueden manejar codificaciones Unicode es sólo
el principio. No importa qué funciones incorpore el lenguaje; es primordial
conocer la especificación Unicode. Por ejemplo, un programa que asuma que sólo
hay mayúsculas y minúsculas estará haciendo una suposición errónea.