PHP 5.4.31 Released

Cadenas de caracteres (Strings)

Un string 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, por lo que no tiene 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 con 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.

<?php
echo 'Esto es una cadena sencilla';

echo 
'También puede incluir nuevas líneas en
un string de esta forma, ya que es
correcto hacerlo así'
;

// Resultado: Arnold una vez dijo: "I'll be back"
echo 'Arnold una vez dijo: "I\'ll be back"';

// Resultado: Ha borrado C:\*.*?
echo 'Ha borrado C:\\*.*?';

// Resultado: Ha borrado C:\*.*?
echo 'Ha borrado C:\*.*?';

// Resultado: Esto no se expandirá: \n una nueva línea
echo 'Esto no se expandirá: \n una nueva línea';

// Resultado: Las variables $tampoco se $expandirán
echo 'Las variables $tampoco se $expandirán';
?>

Entrecomillado doble

Si un string está delimitado con comillas dobles ("), PHP interpretará más 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.0)
\f avance de página (FF o 0x0C (12) en ASCII) (desde PHP 5.2.5)
\\ barra invertida
\$ signo del 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
\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

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, la barra invertida en \{$var} no se mostraba.

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 pueden seguir empleando los códigos de escape indicados arriba. Aunque 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 aqui dentro...
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 PHP o grandes fragmentos de texto sin necesidad de escaparlo. 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, <<<, usada 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

Nota:

A diferencia de heredoc, nowdoc se puede emplear en cuaquier contexto de datos estáticos. Un ejemplo típico es la inicialización de propiedades o constantes de clase:

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.

<?php
$jugo 
"manzana";

echo 
"Él tomó algo de jugo de $jugo.".PHP_EOL
// Inválido. "s" es un carácter válido para un nombre de variable, pero la variable es $jugo.
echo "Él tomó algo de jugo hecho de $jugos.";
?>

El resultado del ejemplo sería:

Él tomó algo de jugo de manzana.
Él tomó algo de jugo hecho de .

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 
gente {
    public 
$john "John Smith";
    public 
$jane "Jane Smith";
    public 
$robert "Robert Paulsen";
    
    public 
$smith "Smith";
}

$gente = new gente();

echo 
"$gente->john tomó algo de jugo de $jugos[0].".PHP_EOL;
echo 
"$gente->john entonces dijo hola a $gente->jane.".PHP_EOL;
echo 
"La esposa de $gente->john saludó a $gente->robert.".PHP_EOL;
echo 
"$gente->robert saludó a los dos $gente->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:

<?php
// Mostrar todos los errores
error_reporting(E_ALL);

$genial 'fantástico';

// No funciona, muestra: Esto es { fantástico}
echo "Esto es { $genial}";

// Funciona, muestra: Esto es fantástico
echo "Esto es {$genial}";
echo 
"Esto es ${genial}";

// Funciona
echo "Este cuadrado tiene {$cuadrado->width}00 centímetros de lado.";


// Funciona, las claves entre comillas sólo funcionan usando la sintaxis de llaves
echo "Esto funciona: {$arr['clave']}";


// Funciona
echo "Esto funciona: {$arr[4][3]}";

// Esto no funciona por la misma razón que $foo[bar] es incorrecto fuera de un string.
// En otras palabras, aún funcionaría, pero solamente porque PHP primero busca una
// constante llamada foo; se emitirá un error del nivel E_NOTICE
// (constante no definida).
echo "Esto está mal: {$arr[foo][3]}"

// Funciona. Cuando se usan arrays multidimensionales, emplee siempre llaves que delimiten
// a los arrays cuando se encuentre dentro de un string
echo "Esto funciona: {$arr['foo'][3]}";

// Funciona.
echo "Esto funciona: " $arr['foo'][3];

echo 
"Esto también funciona: {$obj->valores[3]->nombre}";

echo 
"Este es el valor de la variable llamada $nombre{${$nombre}}";

echo 
"Este es el valor de la variable llamada por el valor devuelto por getNombre(): {${getNombre()}}";

echo 
"Este es el valor de la variable llamada por el valor devuelto por \$objeto->getNombre(): {${$objeto->getNombre()}}";

//No funciona, muestra: Esto es el valor devuelto por getNombre(): {getNombre()}
echo "Esto es el valor devuelto por getNombre(): {getNombre()}";
?>

También es posible acceder a las propiedades de una clase usando variables dentro de un string empleando esta sintaxis.

<?php
class foo {
    var 
$bar 'Soy bar.';
}

$foo = new foo();
$bar 'bar';
$baz = array('foo''bar''baz''quux');
echo 
"{$foo->$bar}\n";
echo 
"{$foo->$baz[1]}\n";
?>

El resultado del ejemplo sería:

Soy bar.
Soy bar.

Nota:

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.

<?php
// Mostrar todos los errores.
error_reporting(E_ALL);

class 
cervezas {
    const 
refresco 'zarzaparrilla';
    public static 
$ale 'ipa';
}

$zarzaparrilla 'A & W';
$ipa 'Alexander Keith\'s';

// Funciona; muestra: Me gusta una A & W
echo "Me gusta una {${cervezas::refresco}}\n";

// También funciona; muestra: Me gusta una Alexander Keith's
echo "Me gusta una {${cervezas::$ale}}\n";
?>

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 hace que se rellene 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 lee 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 string de codificaciones de un solo byte, 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 de arriba 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 de arriba 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 {}.

Funciones y operadores útiles

Los string pueden ser concatenados empleando el operador '.' (punto). Fíjese que el operador '+' (suma) no servirá para concatenar. Consulte los operadores de string para más información.

Hay una serie de funciones útiles para la manipulación de string.

Consulte la sección de funciones de string para funciones generales, y las funciones de expresiones regulares o las funciones de expresiones regulares compatibles con Perl para características avanzadas de búsqueda y sustitución.

También existen funciones para string de URL, y funciones para encriptar/desencriptar string (mcrypt y mhash).

Finalmente, también existen las funciones para el tipo carácter.

Conversión a string

Un valor puede convertirse a un string precediéndole (string) o mediante la función strval(). La conversión automática a string tiene lugar en el ámbito de una expresión que necesite 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 pueden ayudarle a enterderlo con más claridad. 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 en 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 script de configuración regional (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.

Los resource siempre son convertidos en string con la estructura "Resource id #1", donde 1 es el número de recurso asignado al resource por PHP en tiempo de 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 fue construido 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.

<?php
$foo 
"10.5";                   // $foo es float (11.5)
$foo "-1.3e3";                 // $foo es float (-1299)
$foo "bob-1.3e3";              // $foo es integer (1)
$foo "bob3";                   // $foo es integer (1)
$foo "10 pequeños cerdos";     // $foo es integer (11)
$foo "10.2 pequeños cerditos"// $foo es float (14.2)
$foo "10.0 cerdos " 1;           // $foo es float (11)
$foo "10.0 cerdos " 1.0;         // $foo es float (11)     
?>

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:

<?php
echo "\$foo==$foo; tipo : " gettype ($foo) . "<br />\n";
?>

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 de dato 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, 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 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ía 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 la configuración regional 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 de la configuración regional. Por ejemplo, strtoupper("á") podría devolver "Á" si la configuración regional está correctamente establecida 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 de la configuración regional 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.

add a note add a note

User Contributed Notes 41 notes

up
38
gtisza at gmail dot com
2 years ago
The documentation does not mention, but a closing semicolon at the end of the heredoc is actually interpreted as a real semicolon, and as such, sometimes leads to syntax errors.

This works:

<?php
$foo
= <<<END
abcd
END;
?>

This does not:

<?php
foo
(<<<END
abcd
END;
);
// syntax error, unexpected ';'
?>

Without semicolon, it works fine:

<?php
foo
(<<<END
abcd
END
);
?>
up
2
necrodust44 at gmail dot com
4 months ago
String conversion to numbers.

Unfortunately, the documentation is not correct.

«The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero).»

It is not said and is not shown in examples throughout the documentation that, while converting strings to numbers, leading space characters are ignored, like with the strtod function.

<?php
   
echo "     \v\f    \r   1234" + 1;    // 1235
   
var_export ("\v\f    \r   1234" == "1234");    // true
?>

However, PHP's behaviour differs even from the strtod's. The documentation says that if the string contains a "e" or "E" character, it will be parsed as a float, and suggests to see the manual for strtod for more information. The manual says

«A hexadecimal number consists of a "0x" or "0X" followed by a nonempty sequence of hexadecimal digits possibly containing a radix character, optionally followed by a binary exponent.  A binary exponent consists of a 'P' or 'p', followed by an optional plus or minus sign, followed by a nonempty sequence of decimal digits, and indicates multiplication by a power of 2.»

But it seems that PHP does not recognise the exponent or the radix character.

<?php
   
echo "0xEp4" + 1;     // 15
?>

strtod also uses the current locale to choose the radix character, but PHP ignores the locale, and the radix character is always 2E. However, PHP uses the locale while converting numbers to strings.

With strtod, the current locale is also used to choose the space characters, I don't know about PHP.
up
11
chAlx at findme dot if dot u dot need
5 years ago
To save Your mind don't read previous comments about dates  ;)

When both strings can be converted to the numerics (in ("$a" > "$b") test) then resulted numerics are used, else FULL strings are compared char-by-char:

<?php
var_dump
('1.22' > '01.23'); // bool(false)
var_dump('1.22.00' > '01.23.00'); // bool(true)
var_dump('1-22-00' > '01-23-00'); // bool(true)
var_dump((float)'1.22.00' > (float)'01.23.00'); // bool(false)
?>
up
13
atnak at chejz dot com
10 years ago
Here is a possible gotcha related to oddness involved with accessing strings by character past the end of the string:

$string = 'a';

var_dump($string[2]);  // string(0) ""
var_dump($string[7]);  // string(0) ""
$string[7] === '';  // TRUE

It appears that anything past the end of the string gives an empty string..  However, when E_NOTICE is on, the above examples will throw the message:

Notice:  Uninitialized string offset:  N in FILE on line LINE

This message cannot be specifically masked with @$string[7], as is possible when $string itself is unset.

isset($string[7]);  // FALSE
$string[7] === NULL;  // FALSE

Even though it seems like a not-NULL value of type string, it is still considered unset.
up
6
deminy at deminy dot net
4 years ago
Although current documentation says 'A string literal can be specified in four different ways: ...', actually there is a fifth way to specify a (binary) string:

<?php $binary = b'This is a binary string'; ?>

The above statement declares a binary string using the 'b' prefix, which is available since PHP 5.2.1. However, it will only have effect as of PHP 6.0.0, as noted on http://www.php.net/manual/en/function.is-binary.php .
up
6
dee jay simple 0 0 7 at ge mahl dot com
3 years ago
I recently discovered the joys of using heredoc with sprintf and positions. Useful if you want some code to iterate, you can repeat placeholders.

<?php

function getNumber($num = 0) {
   
$foo = rand(1,20);
    return (
$foo + $num);
}
function
getString() {
   
$foo = array("California","Oregon","Washington");
   
shuffle($foo);
    return
$foo[0];
}
function
getDiv() {
   
$num = getNumber();
   
$div = sprintf( "<div>%s</div>", getNumber(rand(-5,5)) );
    return
$div;
}
$string = <<<THESTRING
I like the state of %1\$s <br />
I picked: %2\$d as a number, <br />
I also picked %2\$d as a number again <br />
%3\$s<br />
%3\$s<br />
%3\$s<br />
%3\$s<br />
%3\$s<br />
THESTRING;

$returnText = sprintf$string, getString(),getNumber(),getDiv()  );

echo
$returnText;

?>

Expected output of the above code:

I like the state of Oregon
I picked: 15 as a number,
I also picked 15 as a number again
5

5

5

5

5
up
4
php at richardneill dot org
1 year ago
Leading zeroes in strings are (least-surprise) not treated as octal.
Consider:
  $x = "0123"  + 0;  
  $y = 0123 + 0;
  echo "x is $x, y is $y";    //prints  "x is 123, y is 83"
in other words:
* leading zeros in numeric literals in the source-code are interpreted as "octal", c.f. strtol().
* leading zeros in strings (eg user-submitted data), when cast (implicitly or explicitly) to integer are ignored, and considered as decimal, c.f. strtod().
up
5
og at gams dot at
7 years ago
easy transparent solution for using constants in the heredoc format:
DEFINE('TEST','TEST STRING');

$const = get_defined_constants();

echo <<<END
{$const['TEST']}
END;

Result:
TEST STRING
up
2
headden at karelia dot ru
5 years ago
Here is an easy hack to allow double-quoted strings and heredocs to contain arbitrary expressions in curly braces syntax, including constants and other function calls:

<?php

// Hack declaration
function _expr($v) { return $v; }
$_expr = '_expr';

// Our playground
define('qwe', 'asd');
define('zxc', 5);

$a=3;
$b=4;

function
c($a, $b) { return $a+$b; }

// Usage
echo "pre {$_expr(1+2)} post\n"; // outputs 'pre 3 post'
echo "pre {$_expr(qwe)} post\n"; // outputs 'pre asd post'
echo "pre {$_expr(c($a, $b)+zxc*2)} post\n"; // outputs 'pre 17 post'

// General syntax is {$_expr(...)}
?>
up
1
m021 at springtimesoftware dot com
2 years ago
Heredoc literals delete any trailing space (tabs and blanks) on each line. This is unexpected, since quoted strings do not do this. This is probably done for historical reasons, so would not be considered a bug.
up
1
.
5 days ago
Here's an observation of HEREDOC:

<?php
function foo() {
    return <<<EOT
Hello World
EOT
}
?>

This will give you a fatal error:
Parse error: syntax error, unexpected '}' in foo.php on line 6

To fix this, add a semicolon. I encountered this issue after removing the semicolon because my editor wasn't highlighting correctly.

In my case, this works without messing up my editor's highlighting:

<?php
function foo() {
    return <<<EOT
Hello World
EOT
    ;
}
?>

HTH
up
1
rkfranklin+php at gmail dot com
6 years ago
If you want to use a variable in an array index within a double quoted string you have to realize that when you put the curly braces around the array, everything inside the curly braces gets evaluated as if it were outside a string.  Here are some examples:

<?php
$i
= 0;
$myArray[Person0] = Bob;
$myArray[Person1] = George;

// prints Bob (the ++ is used to emphasize that the expression inside the {} is really being evaluated.)
echo "{$myArray['Person'.$i++]}<br>";

// these print George
echo "{$myArray['Person'.$i]}<br>";
echo
"{$myArray["Person{$i}"]}<br>";

// These don't work
echo "{$myArray['Person$i']}<br>";
echo
"{$myArray['Person'$i]}<br>";

// These both throw fatal errors
// echo "$myArray[Person$i]<br>";
//echo "$myArray[Person{$i}]<br>";
?>
up
1
lelon at lelon dot net
9 years ago
You can use the complex syntax to put the value of both object properties AND object methods inside a string.  For example...
<?php
class Test {
    public
$one = 1;
    public function
two() {
        return
2;
    }
}
$test = new Test();
echo
"foo {$test->one} bar {$test->two()}";
?>
Will output "foo 1 bar 2".

However, you cannot do this for all values in your namespace.  Class constants and static properties/methods will not work because the complex syntax looks for the '$'.
<?php
class Test {
    const
ONE = 1;
}
echo
"foo {Test::ONE} bar";
?>
This will output "foo {Test::one} bar".  Constants and static properties require you to break up the string.
up
-2
Ray.Paseur often uses Gmail
4 months ago
In Example #8, above, consider the risk to the script if a programmer were to define('koolaid1', 'XYZ');  For this reason it's wise to use quotes around literal-string associative array keys.  As written without quotes, PHP should raise a Notice.
up
0
harmor
5 years ago
So you want to get the last character of a string using "String access and modification by character"?  Well negative indexes are not allowed so $str[-1] will return an empty string.

<?php
//Tested using: PHP 5.2.5

$str = 'This is a test.';

$last = $str[-1];                  //string(0) ""
$realLast = $str[strlen($str)-1];  //string(1) "."
$substr = substr($str,-1);         //string(1) "."

echo '<pre>';
var_dump($last);
var_dump($realLast);
var_dump($substr);
up
0
webmaster at rephunter dot net
8 years ago
Use caution when you need white space at the end of a heredoc. Not only is the mandatory final newline before the terminating symbol stripped, but an immediately preceding newline or space character is also stripped.

For example, in the following, the final space character (indicated by \s -- that is, the "\s" is not literally in the text, but is only used to indicate the space character) is stripped:

$string = <<<EOT
this is a string with a terminating space\s
EOT;

In the following, there will only be a single newline at the end of the string, even though two are shown in the text:

$string = <<<EOT
this is a string that must be
followed by a single newline

EOT;
up
-1
cvolny at gmail dot com
5 years ago
I commented on a php bug feature request for a string expansion function and figured I should post somewhere it might be useful:

using regex, pretty straightforward:
<?php
function stringExpand($subject, array $vars) {
   
// loop over $vars map
   
foreach ($vars as $name => $value) {
       
// use preg_replace to match ${`$name`} or $`$name`
       
$subject = preg_replace(sprintf('/\$\{?%s\}?/', $name), $value,
$subject);
    }
   
// return variable expanded string
   
return $subject;
}
?>

using eval() and not limiting access to only certain variables (entire current symbol table including [super]globals):

<?php
function stringExpandDangerous($subject, array $vars = array(), $random = true) {
   
       
// extract $vars into current symbol table
       
extract($vars);
       
       
$delim;
       
// if requested to be random (default), generate delim, otherwise use predefined (trivially faster)
       
if ($random)
           
$delim = '___' . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . chr(mt_rand(65,90)) . '___';
        else
           
$delim = '__ASDFZXCV1324ZXCV__'// button mashing...
       
        // built the eval code
       
$statement = "return <<<$delim\n\n" . $subject . "\n$delim;\n";
       
       
// execute statement, saving output to $result variable
       
$result = eval($statement);
       
       
// if eval() returned FALSE, throw a custom exception
       
if ($result === false)
            throw new
EvalException($statement);
       
       
// return variable expanded string
       
return $result;
    }
?>

I hope that helps someone, but I do caution against using the eval() route even if it is tempting.  I don't know if there's ever a truely safe way to use eval() on the web, I'd rather not use it.
up
-1
shd at earthling dot net
4 years ago
If you want a parsed variable surrounded by curly braces, just double the curly braces:

<?php
  $foo
= "bar";
  echo
"{{$foo}}";
?>

will just show {bar}. The { is special only if followed by the $ sign and matches one }. In this case, that applies only to the inner braces. The outer ones are not escaped and pass through directly.
up
-1
bryant at zionprogramming dot com
7 years ago
As of (at least) PHP 5.2, you can no longer convert an object to a string unless it has a __toString method. Converting an object without this method now gives the error:

PHP Catchable fatal error:  Object of class <classname> could not be converted to string in <file> on line <line>

Try this code to get the same results as before:

<?php

if (!is_object($value) || method_exists($value, '__toString')) {
   
$string = (string)$value;
} else {
   
$string = 'Object';
}

?>
up
-1
bishop
8 years ago
You may use heredoc syntax to comment out large blocks of code, as follows:
<?php
<<<_EOC
    // end-of-line comment will be masked... so will regular PHP:
    echo (
$test == 'foo' ? 'bar' : 'baz');
    /* c-style comment will be masked, as will other heredocs (not using the same marker) */
    echo <<<EOHTML
This is text you'll never see!       
EOHTML;
    function defintion(
$params) {
        echo 'foo';
    }
    class definition extends nothing     {
       function definition(
$param) {
          echo 'do nothing';
       }      
    }

    how about syntax errors?; = gone, I bet.
_EOC;
?>

Useful for debugging when C-style just won't do.  Also useful if you wish to embed Perl-like Plain Old Documentation; extraction between POD markers is left as an exercise for the reader.

Note there is a performance penalty for this method, as PHP must still parse and variable substitute the string.
up
-2
steve at mrclay dot org
5 years ago
Simple function to create human-readably escaped double-quoted strings for use in source code or when debugging strings with newlines/tabs/etc.

<?php
function doubleQuote($str) {
   
$ret = '"';
    for (
$i = 0, $l = strlen($str); $i < $l; ++$i) {
       
$o = ord($str[$i]);
        if (
$o < 31 || $o > 126) {
            switch (
$o) {
                case
9: $ret .= '\t'; break;
                case
10: $ret .= '\n'; break;
                case
11: $ret .= '\v'; break;
                case
12: $ret .= '\f'; break;
                case
13: $ret .= '\r'; break;
                default:
$ret .= '\x' . str_pad(dechex($o), 2, '0', STR_PAD_LEFT);
            }
        } else {
            switch (
$o) {
                case
36: $ret .= '\$'; break;
                case
34: $ret .= '\"'; break;
                case
92: $ret .= '\\\\'; break;
                default:
$ret .= $str[$i];
            }
        }
    }
    return
$ret . '"';
}
?>
up
-2
Richard Neill
7 years ago
Unlike bash, we can't do
  echo "\a"       #beep!

Of course, that would be rather meaningless for PHP/web, but it's useful for PHP-CLI. The solution is simple:  echo "\x07"
up
-3
Liesbeth
4 years ago
If you need to emulate a nowdoc in PHP < 5.3, try using HTML mode and output capturing. This way '$' or '\n' in your string won't be a problem anymore (but unfortunately, '<?' will be).

<?php

// Start of script

ob_start(); ?>
  A text with 'quotes'
    and $$$dollars$$$.
<?php $input = ob_get_contents(); ob_end_clean();

// Do what you want with $input
echo "<pre>" . $input . "</pre>";

?>
up
-4
saamde at gmail dot com
4 years ago
Watch out for the "unexpected T_SL" error.  This appears to occur when there is white space just after "<<<EOT" and since it's white space it's real hard to spot the error in your code.
up
-5
Michael
3 years ago
Just want to mention that if you want a literal { around a variable within a string, for example if you want your output to be something like the following:

{hello, world}

and all that you put inside the {} is a variable, you can do a double {{}}, like this:

$test = 'hello, world';
echo "{{$test}}";
up
-5
Evan K
6 years ago
I encountered the odd situation of having a string containing unexpanded escape sequences that I wanted to expand, but also contained dollar signs that would be interpolated as variables.  "$5.25\n", for example, where I want to convert \n to a newline, but don't want attempted interpolation of $5.

Some muddling through docs and many obscenties later, I produced the following, which expands escape sequences in an existing string with NO interpolation.

<?php

// where we do all our magic
function expand_escape($string) {
    return
preg_replace_callback(
       
'/\\\([nrtvf]|[0-7]{1,3}|[0-9A-Fa-f]{1,2})?/',
       
create_function(
           
'$matches',
           
'return ($matches[0] == "\\\\") ? "" : eval( sprintf(\'return "%s";\', $matches[0]) );'
       
),
       
$string
   
);
}

// a string to test, and show the before and after
$before = 'Quantity:\t500\nPrice:\t$5.25 each';
$after = expand_escape($before);
var_dump($before, $after);

/* Outputs:
string(34) "Quantity:\t500\nPrice:\t$5.25 each"
string(31) "Quantity:    500
Price:    $5.25 each"
*/

?>
up
-5
Denis R.
2 years ago
Hi.

I noticed that the documentation does not mention that when you have an XML element which contains a dash (-) in its name can only be accessed using the bracelets notation.
For example:
<xml version="1">
<root>
   <element-one>value4element-one</element-one>
</root>

to access the above 'element-one' using SimpleXML you need to use the following:

$simpleXMLObj->root->{'element-one'}

to retrieve the value.

Hope this helps,
Denis R.
up
-6
mcamiano at ncsu dot edu
1 year ago
Regarding the lack of complex expression interpolation, just assign an identity function to a variable and call it:

function id($arg) { return $arg; }

$expr = id;

echo "Field is: {$expr( "1 ". ucfirst('whatzit')) }";

It is slower due to an additional function call, but it does avoid the assignment of a one-shot temporary variable. When there are a lot of very simple value transformations made just for display purposes, it can de-clutter code.
up
-4
www.feisar.de
10 years ago
watch out when comparing strings that are numbers. this example:

<?php

$x1
= '111111111111111111';
$x2 = '111111111111111112';

echo (
$x1 == $x2) ? "true\n" : "false\n";

?>

will output "true", although the strings are different. With large integer-strings, it seems that PHP compares only the integer values, not the strings. Even strval() will not work here.

To be on the safe side, use:

$x1 === $x2
up
-6
&#34;Sascha Ziemann&#34;
4 years ago
Empty strings seem to be no real strings, because they behave different to strings containing data. Here is an example.

It is possible to change a character at a specific position using the square bracket notation:
<?php
$str
= '0';
$str[0] = 'a';
echo
$str."\n"; // => 'a'
?>

It is also possible to change a character with does not exist, if the index is "behind" the end of the string:
<?php
$str
= '0';
$str[1] = 'a';
echo
$str."\n"; // => 0a
?>

But if you do that on an empty string, the string gets silently converted into an array:
<?php
$str
= '';
$str[0] = 'a';
echo
$str."\n"; // => Array
?>
up
-5
DELETETHIS dot php at dfackrell dot mailshell dot com
8 years ago
Just some quick observations on variable interpolation:

Because PHP looks for {? to start a complex variable expression in a double-quoted string, you can call object methods, but not class methods or unbound functions.

This works:

<?php
class a {
    function
b() {
        return
"World";
    }
}
$c = new a;
echo
"Hello {$c->b()}.\n"
?>

While this does not:

<?php
function b() {
    return
"World";
}
echo
"Hello {b()}\n";
?>

Also, it appears that you can almost without limitation perform other processing within the argument list, but not outside it.  For example:

<?
$true = true;
define("HW", "Hello World");
echo "{$true && HW}";
?>

gives: Parse error: parse error, unexpected T_BOOLEAN_AND, expecting '}' in - on line 3

There may still be some way to kludge the syntax to allow constants and unbound function calls inside a double-quoted string, but it isn't readily apparent to me at the moment, and I'm not sure I'd prefer the workaround over breaking out of the string at this point.
up
-7
Jonathan Lozinski
9 years ago
A note on the heredoc stuff.

If you're editing with VI/VIM and possible other syntax highlighting editors, then using certain words is the way forward.  if you use <<<HTML for example, then the text will be hightlighted for HTML!!

I just found this out and used sed to alter all EOF to HTML.

JAVASCRIPT also works, and possibly others.  The only thing about <<<JAVASCRIPT is that you can't add the <script> tags..,  so use HTML instead, which will correctly highlight all JavaScript too..

You can also use EOHTML, EOSQL, and EOJAVASCRIPT.
up
-9
sgbeal at googlemail dot com
2 years ago
The docs say: "Heredoc text behaves just like a double-quoted string, without the double quotes" but there is a notable hidden exception to that rule: the final newline in the string (the one before closing heredoc token) is elided. i.e. if you have:

$foo = <<<EOF
a
b
c
EOF;

the result is equivalent to "a\nb\nc", NOT "a\nb\nc\n" like the docs imply.
up
-5
Anonymous
3 months ago
$my_int = "12,140";
echo  1 + $my_int ;

Returns 13 not the expected 12141
up
-11
Obeliks
5 years ago
Expectedly <?php $string[$x] ?> and <?php substr($string, $x, 1) ?> will yield the same result... normally!

However, when you turn on the  Function Overloading Feature (http://php.net/manual/en/mbstring.overload.php), this might not be true!

If you use this Overloading Feature with 3rd party software, you should check for usage of the String access operator, otherwise you might be in for some nasty surprises.
up
-10
fmouse at fmp dot com
7 years ago
It may be obvious to some, but it's convenient to note that variables _will_ be expanded inside of single quotes if these occur inside of a double-quoted string.  This can be handy in constructing exec calls with complex data to be passed to other programs.  e.g.:

$foo = "green";
echo "the grass is $foo";
the grass is green

echo 'the grass is $foo';
the grass is $foo

echo "the grass is '$foo'";
the grass is 'green'
up
-15
penda ekoka
7 years ago
error control operator (@) with heredoc syntax:

the error control operator is pretty handy for supressing minimal errors or omissions. For example an email form that request some basic non mandatory information to your users. Some may complete the form, other may not. Lets say you don't want to tweak PHP for error levels and you just wish to create some basic template that will be emailed to the admin with the user information submitted. You manage to collect the user input in an array called $form:

<?php
// creating your mailer
$mailer = new SomeMailerLib();
$mailer->from = ' System <mail@yourwebsite.com>';
$mailer->to = 'admin@yourwebsite.com';
$mailer->subject = 'New user request';
// you put the error control operator before the heredoc operator to suppress notices and warnings about unset indices like this
$mailer->body = @<<<FORM
Firstname = {$form['firstname']}
Lastname =
{$form['lastname']}
Email =
{$form['email']}
Telephone =
{$form['telephone']}
Address =
{$form['address']}
FORM;

?>
up
-18
Ultimater at gmail dot com
3 years ago
If you require a NowDoc but don't have support for them on your server -- since your PHP version is less than PHP 5.3.0 -- and you are in need of a workaround, I'd suggest using PHP's __halt_compiler() which is basically a knock-off of Perl's __DATA__ token if you are familiar with it.

Give this a run to see my suggestion in action:

<?php
//set $nowDoc to a string containing a code snippet for the user to read
$nowDoc = file_get_contents(__FILE__,null,null,__COMPILER_HALT_OFFSET__);
$nowDoc=highlight_string($nowDoc,true);

echo <<<EOF
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>NowDoc support for PHP &lt; 5.3.0</title>
<meta name="author" content="Ultimater at gmail dot com" />
<meta name="about-this-page"
content="Note that I built this code explicitly for the
php.net documenation for demonstrative purposes." />
<style type="text/css">
body{text-align:center;}
table.border{background:#e0eaee;margin:1px auto;padding:1px;}
table.border td{padding:5px;border:1px solid #8880ff;text-align:left;
background-color:#eee;}
code ::selection{background:#5f5color:white;}
code ::-moz-selection{background:#5f5;color:white;}
a{color:#33a;text-decoration:none;}
a:hover{color:rgb(3,128,252);}
</style>
</head>
<body>
<h1 style="margin:1px auto;">
<a
href="http://php.net/manual/en/language.types.string.php#example-77">
Example #8 Simple syntax example
</a></h1>
<table class="border"><tr><td>
$nowDoc
</td></tr></table></body></html>
EOF;

__halt_compiler()
//Example code snippet we want displayed on the webpage
//note that the compiler isn't actually stopped until the semicolon
;<?php
$juices
= array("apple", "orange", "koolaid1" => "purple");

echo
"He drank some $juices[0] juice.".PHP_EOL;
echo
"He drank some $juices[1] juice.".PHP_EOL;
echo
"He drank some juice made of $juice[0]s.".PHP_EOL; // Won't work
echo "He drank some $juices[koolaid1] juice.".PHP_EOL;

class
people {
    public
$john = "John Smith";
    public
$jane = "Jane Smith";
    public
$robert = "Robert Paulsen";
   
    public
$smith = "Smith";
}

$people = new people();

echo
"$people->john drank some $juices[0] juice.".PHP_EOL;
echo
"$people->john then said hello to $people->jane.".PHP_EOL;
echo
"$people->john's wife greeted $people->robert.".PHP_EOL;
echo
"$people->robert greeted the two $people->smiths."; // Won't work
?>
up
-28
Salil Kothadia
5 years ago
An interesting finding about Heredoc "syntax error, unexpected $end".
I got this error because I did not use the php close tag "?>" and I had no code after the heredoc code.

foo1.php code gives "syntax error, unexpected $end".
But in foo2.php and foo3.php, when you add a php close tag or when you have some more code after heredoc it works fine.

Example Code:
foo1.php
1. <?php
2. $str
= <<<EOD
3. Example of string
4. spanning multiple lines
5. using heredoc syntax.
6. EOD;
7.

foo2.php
1. <?php
2.
$str = <<<EOD
3. Example of string
4. spanning multiple lines
5. using heredoc syntax.
6. EOD;
7.
8. echo
$str;
9.

foo3.php
1. <?php
2.
$str = <<<EOD
3. Example of string
4. spanning multiple lines
5. using heredoc syntax.
6. EOD;
7. ?>
up
-3
espertalhao04 at hotmail dot com
7 months ago
gtisza at gmail dot com

You incorrectly stated that thee documentation doesn't refer anything about the semicolon at the end of the heredocs and nowdocs  being interpreted as a "real" semicolon.

If you read carefully, you will notice this, in the 1st sentence of the warning about heredocs:

"It is very important to note that the line with the closing identifier must contain no other characters, except a semicolon (;)."

Interesting...
It is refering about semicolons...

But wait, there is more:

http://php.net/manual/en/language.basic-syntax.instruction-separation.php
1st sentence says:
"As in C or Perl, PHP requires instructions to be terminated with a semicolon at the end of each statement."

So, here says that semicolons are statement separators, basicly...

So, if you put a "real" semicolon at the end of these examples:
<?php
    $a
=5;
   
$foo="String";
   
$bar=array();
   
$yep=null;
   
$other=func();
?>
Why shouldn't you put at the end of heredocs and nowdocs?
After all, a heredoc or a nowdoc is simply a string.

You should read more carefully the documentation first before saying any comment.

About serious questions:
I didn't read all comments here, but you can run functions inside strings and heredocs.

And you can even nest them inside {}

Example:
<?php
    $f
=function($x){$a=func_get_args();unset($a[0]);return call_user_func_array($x,$a);};
   
$d=0;
    echo
$b=<<<NUMBERS
4.0909 rounded is: {$f('round',4.0909,$d)}
Time now is:
{$f('time')}
Nested heredocs/nowdocs:
{$f('sprintf',<<<OTHER
Here is an %s of nested %s
OTHER
,
"Example",<<<'NOW'
heredocs and nowdocs
NOW
)}

NUMBERS;

/*echoes (time is system and real time relative):
4.0909 rounded is: 4
Time now is: 1386670912
Nested heredocs/nowdocs: Here is an Example of nested heredocs and nowdocs
*/
?>

It's not pretty, and is hard to read, but sometimes it is useful to confuse curious people (like minifying the code).

Warning: if any function that runs inside a string or heredoc gives a fatal error, the script MAY continue!
up
-10
benl39 at free dot fr
4 months ago
Note that :

<?php
echo 'error' == 0, '<br>'; // TRUE
echo 'error' == '0', '<br>'; // FALSE
echo '0' == 0, '<br>'; // TRUE

// So, 'error' != 'error' ?
?>
To Top