Tema
Strings
Casi todo en la web es texto: nombres, correos, títulos, URLs, mensajes. En esta lección dominarás la creación de strings, la interpolación, heredoc, las funciones esenciales y, muy importante en español, las funciones mb_* que manejan bien acentos y la ñ.
Concepto
Un string es una cadena de caracteres, como un collar de cuentas donde cada cuenta es una letra. Puedes medir el collar, cortarlo, buscar una cuenta, reemplazarla o unir dos collares.
Detalle técnico importante: PHP guarda los strings como bytes. En UTF-8, letras como á, ñ o un emoji ocupan 2 a 4 bytes. Por eso strlen('ñ') devuelve 2. Para texto en español usa las funciones mb_* (multibyte), que cuentan caracteres reales.
Crear strings
php
<?php
$nombre = 'Sofía';
// Comillas simples: literal, sin interpolación (un poco más rápidas)
echo 'Hola, $nombre\n'; // Hola, $nombre\n
// Comillas dobles: interpolan variables y secuencias de escape
echo "Hola, $nombre\n"; // Hola, Sofía + salto de línea
// Escapes en comillas dobles: \n salto, \t tabulador, \" comilla, \$ signo de pesos, \\ barra
echo "Precio: \$150 \"oferta\"";
// Escapar la comilla simple dentro de simples
echo 'It\'s fine';Interpolación compleja con llaves
Para arrays con claves de texto o propiedades de objetos, envuelve la expresión en llaves:
php
<?php
$usuario = ['nombre' => 'Sofía', 'puntos' => 120];
$producto = new stdClass();
$producto->titulo = 'Taza';
echo "Hola, {$usuario['nombre']}, tienes {$usuario['puntos']} puntos.";
echo "Compraste: {$producto->titulo}";
// Separar la variable de texto pegado
$cantidad = 3;
echo "Tienes {$cantidad}x descuento";Heredoc y nowdoc
Para bloques de texto largos (correos, plantillas pequeñas, SQL):
php
<?php
$cliente = 'Ana';
$folio = 'A-1024';
$total = '1,250.00';
// Heredoc: como comillas dobles (interpola)
$correo = <<<TXT
Hola $cliente,
Gracias por tu compra. Tu pedido {$folio} por \${$total} MXN
ya está en preparación.
Saludos,
El equipo de Mi Tienda
TXT;
echo nl2br($correo); // nl2br convierte \n en <br> para verlo en HTML
// Nowdoc: como comillas simples (no interpola). Nota las comillas en 'TXT'
$ejemplo = <<<'TXT'
Las variables como $esta no se reemplazan.
TXT;Desde PHP 7.3, la etiqueta de cierre puede ir indentada y esa indentación se elimina de todas las líneas.
Concatenar
php
<?php
$nombre = 'Ana';
$apellido = 'Ruiz';
$completo = $nombre . ' ' . $apellido;
$completo .= ' (cliente VIP)';
// sprintf: plantillas con formato, muy legible
echo sprintf('%s %s tiene %d años y debe $%.2f', $nombre, $apellido, 30, 1500.5);
// Ana Ruiz tiene 30 años y debe $1500.50Marcadores de sprintf/printf: %s string, %d entero, %f float (%.2f con 2 decimales), %05d rellena con ceros a 5 dígitos, %% un signo de porcentaje.
php
<?php
printf('Folio: %06d', 42); // Folio: 000042
printf('Avance: %d%%', 75); // Avance: 75%Funciones esenciales (con versión mb_)
php
<?php
$texto = ' Programación en PHP ';
// Longitud
strlen('ñandú'); // 7 (bytes) ✗
mb_strlen('ñandú'); // 5 (caracteres) ✓
// Espacios
trim($texto); // 'Programación en PHP'
ltrim($texto); rtrim($texto); // Sólo izquierda / derecha
trim('--hola--', '-'); // 'hola' (quita otros caracteres)
// Mayúsculas y minúsculas
strtoupper('canción'); // 'CANCIóN' ✗ (la ó no cambia en algunas configuraciones)
mb_strtoupper('canción'); // 'CANCIÓN' ✓
mb_strtolower('ÁRBOL'); // 'árbol'
ucfirst('hola mundo'); // 'Hola mundo'
mb_convert_case('josé pérez', MB_CASE_TITLE); // 'José Pérez'
// Buscar
str_contains('Hola mundo', 'mundo'); // true (PHP 8)
str_starts_with('https://x.com', 'https'); // true (PHP 8)
str_ends_with('foto.jpg', '.jpg'); // true (PHP 8)
mb_strpos('Café con leche', 'con'); // 5 (posición) o false
mb_stripos('HOLA', 'hola'); // 0 (sin distinguir mayúsculas)
// Extraer
mb_substr('Programación', 0, 8); // 'Programa'
mb_substr('Programación', -4); // 'ción' (desde el final)
// Reemplazar
str_replace('mundo', 'PHP', 'Hola mundo'); // 'Hola PHP'
str_replace(['á','é'], ['a','e'], 'café, té'); // 'cafe, te'
str_ireplace('HOLA', 'Adiós', 'hola amigo'); // 'Adiós amigo'
// Repetir y rellenar
str_repeat('=', 20); // '===================='
str_pad('7', 3, '0', STR_PAD_LEFT); // '007'
// Dividir y unir
explode(' ', 'uno dos tres'); // ['uno', 'dos', 'tres']
implode('-', ['2026', '10', '18']);// '2026-10-18'
mb_str_split('añil'); // ['a', 'ñ', 'i', 'l']
// Comparar
strcmp('a', 'b'); // < 0
strcasecmp('HOLA', 'hola'); // 0 (iguales sin distinguir mayúsculas)
// Recortar con puntos suspensivos
mb_strimwidth('Este es un texto muy largo para una tarjeta', 0, 20, '...');
// 'Este es un texto ...'Error común
Usar strlen, substr o strtoupper con texto en español. substr('Año', 0, 2) puede cortar la ñ por la mitad y mostrar un carácter roto (A�). Con texto escrito por usuarios, usa siempre mb_strlen, mb_substr, mb_strtoupper.
Buena práctica
Configura la codificación por defecto al inicio de tu aplicación para no tener que pasar 'UTF-8' a cada función mb_*:
php
<?php
mb_internal_encoding('UTF-8');Y asegúrate de que tus archivos estén guardados en UTF-8 (sin BOM) y tu HTML tenga <meta charset="UTF-8"> en el head.
Seguridad: escapar al mostrar
Todo texto que venga del usuario (formularios, URL, base de datos) debe escaparse al imprimirse en HTML. Si no, alguien puede inyectar código JavaScript (ataque XSS).
php
<?php
$comentario = '<script>alert("hackeado")</script>';
echo $comentario; // ✗ ¡El navegador ejecutaría el script!
echo htmlspecialchars($comentario, ENT_QUOTES, 'UTF-8'); // ✓
// <script>alert("hackeado")</script>Lo verás a fondo en XSS. Por ahora: nunca hagas echo de datos del usuario sin htmlspecialchars.
Otras funciones útiles para mostrar texto:
php
<?php
nl2br("Línea 1\nLínea 2"); // 'Línea 1<br />\nLínea 2'
strip_tags('<b>Hola</b> mundo'); // 'Hola mundo' (quita etiquetas)
number_format(1234567.891, 2); // '1,234,567.89'
number_format(1234567.891, 2, ',', '.'); // '1.234.567,89' (formato europeo)Expresiones regulares (introducción)
Para patrones complejos: validar formatos, extraer datos.
php
<?php
// preg_match: ¿coincide? Devuelve 1 o 0
$cp = '44100';
if (preg_match('/^\d{5}$/', $cp)) {
echo 'Código postal válido';
}
// Extraer partes con grupos ()
$fecha = '2026-10-18';
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $fecha, $partes)) {
[, $anio, $mes, $dia] = $partes; // $partes[0] es la coincidencia completa
echo "Día $dia del mes $mes de $anio";
}
// preg_replace: reemplazar por patrón
$telefono = '(33) 1234-5678';
echo preg_replace('/\D/', '', $telefono); // '3312345678' (\D = todo lo que no sea dígito)
// La bandera u activa el modo UTF-8 (necesaria con acentos)
echo preg_replace('/[^\p{L}\s]/u', '', '¡Hola, Ñoño!'); // 'Hola Ñoño'Ejemplo completo: utilidades de texto
php
<?php
declare(strict_types=1);
mb_internal_encoding('UTF-8');
/** Genera un resumen de N caracteres sin cortar palabras. */
function resumen(string $texto, int $max = 100): string
{
$texto = trim(strip_tags($texto));
if (mb_strlen($texto) <= $max) {
return $texto;
}
$corte = mb_substr($texto, 0, $max);
$ultimoEspacio = mb_strrpos($corte, ' ');
if ($ultimoEspacio !== false) {
$corte = mb_substr($corte, 0, $ultimoEspacio);
}
return rtrim($corte, ' ,.;') . '…';
}
/** Oculta parte de un correo: laura.mendez@gmail.com → la*********@gmail.com */
function ocultarEmail(string $email): string
{
[$usuario, $dominio] = explode('@', $email, 2);
$visible = mb_substr($usuario, 0, 2);
return $visible . str_repeat('*', max(mb_strlen($usuario) - 2, 1)) . '@' . $dominio;
}
/** Iniciales para un avatar: "maría josé pérez" → "MP" */
function iniciales(string $nombre): string
{
$partes = preg_split('/\s+/', trim($nombre));
$primera = mb_substr($partes[0], 0, 1);
$ultima = count($partes) > 1 ? mb_substr(end($partes), 0, 1) : '';
return mb_strtoupper($primera . $ultima);
}
echo resumen('PHP es un lenguaje de programación muy popular para crear sitios web dinámicos y aplicaciones.', 50);
// PHP es un lenguaje de programación muy popular…
echo '<br>' . ocultarEmail('laura.mendez@gmail.com');
echo '<br>' . iniciales('maría josé pérez'); // MPEjercicios
- Escribe
contarPalabras(string $texto): intque funcione con varios espacios seguidos (pista:preg_splitostr_word_countno sirve con acentos). - Crea
capitalizarNombre(string $nombre): stringque convierta' jUAN pérez 'en'Juan Pérez'. - Valida que una contraseña tenga al menos 8 caracteres, una mayúscula y un número. Devuelve un array de errores.
Ver solución
php
<?php
function contarPalabras(string $texto): int
{
$texto = trim($texto);
if ($texto === '') {
return 0;
}
return count(preg_split('/\s+/u', $texto));
}
echo contarPalabras(' Hola mundo, ¿cómo estás? '); // 4php
<?php
function capitalizarNombre(string $nombre): string
{
$nombre = preg_replace('/\s+/u', ' ', trim($nombre)); // Un solo espacio entre palabras
return mb_convert_case($nombre, MB_CASE_TITLE, 'UTF-8');
}
echo capitalizarNombre(' jUAN pérez '); // Juan Pérezphp
<?php
function validarPassword(string $pass): array
{
$errores = [];
if (mb_strlen($pass) < 8) {
$errores[] = 'Debe tener al menos 8 caracteres.';
}
if (!preg_match('/[A-Z]/', $pass)) {
$errores[] = 'Debe incluir al menos una mayúscula.';
}
if (!preg_match('/\d/', $pass)) {
$errores[] = 'Debe incluir al menos un número.';
}
return $errores;
}
print_r(validarPassword('hola'));
// ['Debe tener al menos 8 caracteres.', 'Debe incluir al menos una mayúscula.', 'Debe incluir al menos un número.']
print_r(validarPassword('Segura2026')); // []Resumen
- Comillas simples = literal; dobles = interpolan. Usa
{$arr['clave']}para expresiones complejas. - Heredoc (
<<<TXT) para bloques largos con variables; nowdoc (<<<'TXT') sin interpolar. sprintf/printfpara texto con formato.- Con español usa las funciones
mb_*:mb_strlen,mb_substr,mb_strtoupper. - PHP 8 trae
str_contains,str_starts_with,str_ends_with. - Escapa siempre con
htmlspecialcharsal mostrar datos del usuario. preg_matchypreg_replace(con banderau) para patrones.