Skip to content

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.50

Marcadores 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'); // ✓
// &lt;script&gt;alert(&quot;hackeado&quot;)&lt;/script&gt;

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'); // MP

Ejercicios ​

  1. Escribe contarPalabras(string $texto): int que funcione con varios espacios seguidos (pista: preg_split o str_word_count no sirve con acentos).
  2. Crea capitalizarNombre(string $nombre): string que convierta ' jUAN pérez ' en 'Juan Pérez'.
  3. 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?  '); // 4
php
<?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érez
php
<?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/printf para 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 htmlspecialchars al mostrar datos del usuario.
  • preg_match y preg_replace (con bandera u) para patrones.

Academia Web — aprende, copia y construye.