Cadenas de texto en PHP
En esta lección
- Comillas simples y comillas dobles
- Meter variables dentro del texto
- Textos largos: heredoc y nowdoc
- Longitud de una cadena: strlen y mb_strlen
- Mayúsculas y minúsculas
- Quitar espacios: trim
- Buscar dentro de una cadena
- Extraer un trozo: substr
- Reemplazar: str_replace
- Dividir y unir: explode e implode
- Rellenar y repetir
- Dar formato: sprintf, printf y number_format
- Comparar cadenas
- Cadenas y HTML
- Errores frecuentes
- Resumen
Casi todo lo que maneja una web es texto: nombres de usuario, títulos de productos, direcciones de correo, el propio HTML que genera PHP. Una cadena (string) es una secuencia de caracteres, y PHP trae más de cien funciones para trabajar con ellas. En esta lección aprenderás las diferencias entre comillas simples y dobles, cómo meter variables dentro de un texto, cómo medir, buscar, recortar, reemplazar, dividir y dar formato a cadenas, y por qué las tildes y la ñ necesitan funciones especiales.
Comillas simples y comillas dobles
Una cadena se escribe entre comillas simples '...' o dobles "...". La diferencia es qué hace PHP con lo que hay dentro:
- Con comillas dobles, PHP sustituye las variables por su valor y entiende las secuencias de escape como
\n(salto de línea). - Con comillas simples, el texto se queda literalmente como lo escribes.
$ruta = "Faro de Cabo Mayor";
$km = 7;
echo "Ruta: $ruta ($km km)\n";
echo 'Ruta: $ruta ($km km)\n';
echo "\n";
// Ruta: Faro de Cabo Mayor (7 km)
// Ruta: $ruta ($km km)\n
La segunda línea muestra $ruta y \n tal cual, porque las comillas simples no interpretan nada.
¿Cuál usar? Una regla práctica: comillas simples para texto fijo ('Guardar', claves de arrays como $_POST['email']) y dobles cuando quieras meter variables o saltos de línea. La diferencia de velocidad entre ambas es inapreciable; elige por claridad.
Secuencias de escape
Dentro de comillas dobles, la barra invertida \ da un significado especial al carácter que la sigue:
| Secuencia | Significado |
|---|---|
\n | Salto de línea |
\t | Tabulador |
\" | Comilla doble literal |
\$ | Signo de dólar literal (no es una variable) |
\\ | Barra invertida literal |
echo "Precio:\t12 €\n";
echo "Escribe \"salir\" para terminar\n";
echo "La variable se llama \$total\n";
// Precio: 12 €
// Escribe "salir" para terminar
// La variable se llama $total
En comillas simples solo existen dos escapes: \' para una comilla simple y \\ para la barra.
echo 'L\'Hospitalet', "\n";
// L'Hospitalet
Nota: el
\nproduce un salto de línea en el código fuente de la página o en la terminal, pero el navegador lo muestra como un espacio. Para un salto visible en HTML necesitas<br>o un párrafo nuevo.
Meter variables dentro del texto
Que PHP sustituya variables dentro de las comillas dobles se llama interpolación. Funciona directamente con variables simples, pero con arrays u objetos conviene rodear la expresión con llaves { }:
$socio = ['nombre' => 'Lucía', 'cuota' => 35];
$bloques = 12;
echo "Hola, {$socio['nombre']}. Tu cuota es de {$socio['cuota']} €.\n";
echo "Has encadenado {$bloques}º bloque\n";
// Hola, Lucía. Tu cuota es de 35 €.
// Has encadenado 12º bloque
Las llaves sirven también para separar la variable del texto que va pegado: sin ellas, "$bloquesº" buscaría una variable llamada $bloquesº, que no existe.
La alternativa a la interpolación es la concatenación con el punto, que viste en Operadores:
$producto = "Pies de gato";
$talla = 41;
echo "Producto: " . $producto . " (talla " . $talla . ")\n";
// Producto: Pies de gato (talla 41)
Las dos formas son correctas. La interpolación suele leerse mejor en textos con muchas variables; la concatenación es más clara cuando mezclas llamadas a funciones, porque dentro de las comillas no se pueden llamar funciones.
Textos largos: heredoc y nowdoc
Para un texto de varias líneas (un correo, un trozo de HTML), las comillas se vuelven incómodas. PHP ofrece la sintaxis heredoc: empieza con <<< y un identificador que tú eliges, y termina con ese mismo identificador en su propia línea.
$nombre = "Andrés";
$fecha = "sábado 14";
$correo = <<<TXT
Hola, $nombre:
Tu plaza para el curso de iniciación del {$fecha} está confirmada.
Trae ropa cómoda y "muchas ganas".
TXT;
echo $correo, "\n";
// Hola, Andrés:
//
// Tu plaza para el curso de iniciación del sábado 14 está confirmada.
// Trae ropa cómoda y "muchas ganas".
Un heredoc se comporta como las comillas dobles (interpola variables) pero puedes escribir comillas dentro sin escaparlas. Desde PHP 7.3, la sangría del identificador de cierre se quita de todas las líneas, así que puedes indentar el bloque con el resto del código.
Si pones el identificador entre comillas simples (<<<'TXT') obtienes un nowdoc, que se comporta como las comillas simples: no interpreta nada. Es útil para mostrar código de ejemplo.
Longitud de una cadena: strlen y mb_strlen
strlen() devuelve la longitud… pero en bytes, no en caracteres. Con texto en inglés da igual, porque cada letra ocupa un byte. Pero en UTF-8, la codificación que usan todas las webs, la ñ y las letras con tilde ocupan dos bytes:
$barrio = "Peñacastillo";
echo strlen($barrio), "\n";
echo mb_strlen($barrio), "\n";
// 13
// 12
Las funciones que empiezan por mb_ (de multibyte) cuentan caracteres reales. En español, siempre que el resultado dependa de cuántas letras hay (validar que un nombre tiene como máximo 30 caracteres, cortar un resumen…), usa la versión mb_.
| Función de bytes | Versión segura para UTF-8 |
|---|---|
strlen() | mb_strlen() |
substr() | mb_substr() |
strtoupper() | mb_strtoupper() |
strtolower() | mb_strtolower() |
ucfirst() | mb_ucfirst() (PHP 8.4) |
str_pad() | mb_str_pad() (PHP 8.3) |
Mayúsculas y minúsculas
$via = "vía ferrata de la peña";
echo strtoupper($via), "\n";
echo mb_strtoupper($via), "\n";
echo ucfirst("bloque azul"), "\n";
echo ucwords("bloque azul"), "\n";
// VíA FERRATA DE LA PEñA
// VÍA FERRATA DE LA PEÑA
// Bloque azul
// Bloque Azul
strtoupper() solo convierte las letras sin tilde; la í y la ñ se quedan en minúscula. mb_strtoupper() lo hace bien. ucfirst() pone en mayúscula la primera letra y ucwords() la primera de cada palabra.
Un uso muy habitual es comparar sin distinguir mayúsculas: pasa los dos textos a minúsculas antes de comparar.
$respuesta = "SANTANDER";
var_dump(mb_strtolower($respuesta) === "santander");
// bool(true)
Quitar espacios: trim
trim() elimina los espacios, tabuladores y saltos de línea del principio y del final. ltrim() solo los de la izquierda y rtrim() solo los de la derecha. Es lo primero que se hace con cualquier dato que escribe un usuario, como verás en Validar y sanear.
$email = " ana@correo.es \n";
var_dump(trim($email));
var_dump(rtrim("1.250,00 €", " €"));
// string(13) "ana@correo.es"
// string(8) "1.250,00"
El segundo parámetro indica qué caracteres quitar: en el ejemplo, espacios y el símbolo del euro.
Buscar dentro de una cadena
PHP 8 añadió tres funciones muy legibles que devuelven true o false:
$archivo = "foto-escalada-2026.jpg";
var_dump(str_contains($archivo, "escalada"));
var_dump(str_starts_with($archivo, "foto-"));
var_dump(str_ends_with($archivo, ".png"));
// bool(true)
// bool(true)
// bool(false)
Distinguen mayúsculas y minúsculas. Si necesitas ignorarlas, convierte antes a minúsculas.
strpos: en qué posición está
Cuando necesitas saber dónde aparece un texto, usa strpos(). Devuelve la posición (empezando a contar en 0) o false si no lo encuentra. stripos() hace lo mismo sin distinguir mayúsculas.
$frase = "Cuerda de 60 metros";
var_dump(strpos($frase, "60"));
var_dump(strpos($frase, "Cuerda"));
var_dump(strpos($frase, "70"));
// int(10)
// int(0)
// bool(false)
Aquí está la trampa clásica: si el texto está al principio, strpos() devuelve 0, y 0 es un valor falso. Por eso siempre se compara con === false:
$frase = "Cuerda de 60 metros";
if (strpos($frase, "Cuerda") === false) {
echo "No aparece\n";
} else {
echo "Aparece\n";
}
// Aparece
Consejo: si solo quieres saber si un texto contiene otro, usa
str_contains(). Verásstrpos(...) !== falseen mucho código anterior a PHP 8 que hace exactamente eso.
substr_count() cuenta cuántas veces aparece un texto:
echo substr_count("pa-ta-ta-ta", "ta"), "\n";
// 3
Extraer un trozo: substr
substr($texto, $inicio, $longitud) devuelve una parte de la cadena. Si $inicio es negativo, cuenta desde el final; si omites la longitud, llega hasta el final.
$codigo = "RES-2026-0457";
echo substr($codigo, 0, 3), "\n";
echo substr($codigo, 4, 4), "\n";
echo substr($codigo, -4), "\n";
// RES
// 2026
// 0457
También puedes leer un carácter suelto con corchetes, como si la cadena fuera un array: $codigo[0] es "R" y $codigo[-1] es "7". Pero, igual que substr(), trabaja con bytes: con letras acentuadas usa mb_substr().
$titulo = "Escalada en Picos de Europa: guía para empezar";
$resumen = mb_substr($titulo, 0, 20) . "…";
echo $resumen, "\n";
// Escalada en Picos de…
Reemplazar: str_replace
str_replace($buscar, $reemplazo, $texto) cambia todas las apariciones de un texto por otro:
$aviso = "El rocódromo abre de 10:00 a 22:00";
echo str_replace("22:00", "23:00", $aviso), "\n";
// El rocódromo abre de 10:00 a 23:00
Puedes pasar arrays para hacer varios cambios a la vez. Es muy práctico para generar slugs (la parte de la URL de un artículo):
$titulo = "Nudos básicos para escalar";
$slug = str_replace(
[" ", "á", "é", "í", "ó", "ú", "ñ"],
["-", "a", "e", "i", "o", "u", "n"],
mb_strtolower($titulo)
);
echo $slug, "\n";
// nudos-basicos-para-escalar
str_ireplace() hace lo mismo sin distinguir mayúsculas.
Dividir y unir: explode e implode
explode($separador, $texto) parte una cadena en un array usando un separador. implode($separador, $array) hace lo contrario: une los elementos de un array en una cadena.
$etiquetas = "boulder,vía,iniciación";
$lista = explode(",", $etiquetas);
print_r($lista);
echo implode(" | ", $lista), "\n";
// Array
// (
// [0] => boulder
// [1] => vía
// [2] => iniciación
// )
// boulder | vía | iniciación
print_r() muestra el contenido de un array de forma legible; lo usarás mucho en Arrays. Estas dos funciones aparecen constantemente: leer líneas de un CSV, separar nombre y apellidos, mostrar una lista separada por comas…
[$nombre, $dominio] = explode("@", "marta@ejemplo.es");
echo "Usuario: $nombre, dominio: $dominio\n";
// Usuario: marta, dominio: ejemplo.es
Rellenar y repetir
str_pad() rellena una cadena hasta una longitud. Es perfecto para números con ceros a la izquierda o columnas alineadas en la terminal. str_repeat() repite un texto varias veces.
echo str_pad("7", 4, "0", STR_PAD_LEFT), "\n";
echo str_pad("Bloque", 10, "."), "V3\n";
echo str_repeat("★", 4), str_repeat("☆", 1), "\n";
// 0007
// Bloque....V3
// ★★★★☆
Dar formato: sprintf, printf y number_format
sprintf() construye una cadena a partir de una plantilla con huecos que empiezan por %. printf() hace lo mismo pero la imprime directamente.
| Hueco | Qué inserta |
|---|---|
%s | Una cadena |
%d | Un entero |
%.2f | Un decimal con 2 cifras |
%05d | Un entero de 5 cifras rellenado con ceros |
%-10s | Una cadena alineada a la izquierda en 10 posiciones |
%% | Un signo % literal |
$producto = "Magnesio";
$precio = 6.5;
$descuento = 15;
$linea = sprintf("%s: %.2f € (-%d%%)", $producto, $precio, $descuento);
echo $linea, "\n";
printf("Pedido nº %05d\n", 384);
// Magnesio: 6.50 € (-15%)
// Pedido nº 00384
sprintf() usa el punto como separador decimal. Para mostrar cantidades al estilo español (coma decimal y punto en los miles), usa number_format($numero, $decimales, $sepDecimal, $sepMiles):
$facturacion = 15420.5;
echo number_format($facturacion, 2, ",", "."), " €\n";
echo number_format(1234567), "\n";
// 15.420,50 €
// 1,234,567
Sin los dos últimos parámetros, number_format() usa el formato inglés.
Cuidado:
number_format()devuelve una cadena. Úsala solo al mostrar el dato, nunca antes de hacer cálculos:"15.420,50" * 2no da lo que esperas.
Comparar cadenas
Para saber si dos cadenas son iguales, usa ===. Para ordenarlas necesitas saber cuál va antes, y para eso existen:
strcmp($a, $b): devuelve un número negativo si$ava antes,0si son iguales y positivo si va después. Distingue mayúsculas.strcasecmp($a, $b): igual, pero sin distinguir mayúsculas.strnatcmp($a, $b): orden natural, el que esperaría una persona con números dentro del texto.
var_dump(strcmp("foto10.jpg", "foto9.jpg") < 0);
var_dump(strnatcmp("foto10.jpg", "foto9.jpg") < 0);
var_dump(strcasecmp("BOULDER", "boulder"));
// bool(true)
// bool(false)
// int(0)
Con strcmp(), "foto10" va antes que "foto9" porque compara carácter a carácter y "1" es menor que "9". Con strnatcmp(), el 9 va antes que el 10, como es lógico. Estas funciones son las que usarás para ordenar listas en Funciones de arrays.
Cadenas y HTML
Dos funciones relacionan las cadenas con el HTML que genera PHP:
nl2br()convierte los saltos de línea en<br>, para mostrar un texto que el usuario escribió en un<textarea>respetando sus líneas.htmlspecialchars()convierte<,>,&y las comillas en entidades HTML. Es obligatoria antes de imprimir cualquier texto que venga del usuario, para evitar ataques XSS. Lo tienes explicado en Validar y sanear.
$comentario = "Gran vía\n<b>¡Repetiré!</b>";
echo nl2br(htmlspecialchars($comentario)), "\n";
// Gran vía<br />
// <b>¡Repetiré!</b>
Fíjate en el orden: primero se escapa y después se añaden los <br>. Al revés, htmlspecialchars() también escaparía los <br>.
Errores frecuentes
- Esperar que las comillas simples interpreten variables:
'Hola $nombre'muestra$nombretal cual. Usa comillas dobles o concatena. - Comprobar
strpos()conif (strpos(...)): si el texto está en la posición 0, la condición es falsa. Compara con=== falseo usastr_contains(). - Contar letras con
strlen(): con tildes y eñes da más de lo esperado. Usamb_strlen()y el resto de funcionesmb_. - Concatenar con
+: en PHP se une con.;+intenta sumar y da error. - Hacer cálculos con el resultado de
number_format(): es texto con formato, solo para mostrar. - Imprimir datos del usuario sin
htmlspecialchars(): abre la puerta a inyectar HTML y JavaScript en tu página. - Llamar a funciones dentro de las comillas:
"Total: strtoupper($x)"no ejecuta nada. Concatena:"Total: " . strtoupper($x).
Resumen
| Tarea | Función o sintaxis |
|---|---|
| Texto literal / con variables | '...' / "...", {$array['clave']} |
| Texto largo | heredoc <<<TXT ... TXT; |
| Longitud | mb_strlen() (caracteres), strlen() (bytes) |
| Mayúsculas | mb_strtoupper(), mb_strtolower(), ucfirst(), ucwords() |
| Quitar espacios | trim(), ltrim(), rtrim() |
| Buscar | str_contains(), str_starts_with(), str_ends_with(), strpos() === false |
| Extraer | substr(), mb_substr(), $texto[0] |
| Reemplazar | str_replace(), str_ireplace() |
| Dividir / unir | explode() / implode() |
| Rellenar / repetir | str_pad(), str_repeat() |
| Formatear | sprintf(), printf(), number_format() |
| Comparar / ordenar | ===, strcmp(), strcasecmp(), strnatcmp() |
| HTML | htmlspecialchars(), nl2br() |
En la siguiente lección harás que tus programas tomen decisiones: condicionales.
Pon a prueba lo que has aprendido
¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.