Arrays asociativos en PHP: la guía práctica de un senior
En PHP no hay dos tipos de array: hay uno, un mapa ordenado. Entender esa frase evita la mayoría de bugs con claves, foreach por referencia, orden e in_array.
Tabla de contenidos
Cada pocos meses alguien me enseña un bug que empieza con la misma frase: "pero si el array tenía la clave, lo he comprobado". Casi siempre el problema no está en su lógica, sino en una idea equivocada que arrastra desde el primer tutorial que leyó: que en PHP hay dos tipos de array, los "indexados" y los "asociativos", y que funcionan distinto. No es así. En PHP solo hay una estructura de array, y entender qué es de verdad te ahorra la mayoría de esos sustos. Aquí va lo que importa: cómo se declaran, cómo se recorren con foreach y, sobre todo, las trampas con claves, orden y comparaciones que ningún manual introductorio cuenta y que sí machacan datos en producción.
Los arrays asociativos en PHP no son un tipo aparte: son la misma cosa que cualquier otro array, mirada de cerca. Cuando asumes eso, dejas de pelearte con casos que parecían magia negra.
En PHP solo hay un tipo de array: un mapa ordenado
Lo dice el propio manual de PHP sin rodeos: "un array en PHP es en realidad un mapa ordenado. Un mapa es un tipo que asocia valores a claves" (php.net). Ahí está todo. Un array es un conjunto de pares clave → valor donde el orden de inserción se conserva. No hay "arrays de lista" por un lado y "arrays de diccionario" por otro; hay un mapa, y lo que llamamos "array indexado" es simplemente un mapa cuyas claves son enteros consecutivos que empiezan en 0.
Las claves solo pueden ser de dos tipos: int o string. Los valores, cualquier cosa. El orden es el de inserción, no el de la clave: si insertas la clave 10 y luego la 3, el array recorre primero el 10. Esto importa más de lo que parece, porque explica por qué existen dos familias de funciones de ordenación (las que reindexan y las que no) y por qué algunas operaciones "rompen" el orden que esperabas.
Interioriza esta frase y la mayoría de las rarezas de los arrays de PHP dejan de serlo: no ordenas un array asociativo distinto de como ordenas uno "normal", porque no son distintos. Solo eliges si quieres conservar las claves o tirarlas.
Cómo se declara un array: de array() a los corchetes []
Hay dos sintaxis. La antigua, array(), y la corta, [], disponible desde PHP 5.4. Hoy no hay motivo para escribir array() en código nuevo: usa corchetes.
// Forma antigua, todavía la ves en librerías viejas
$config = array('host' => 'localhost', 'port' => 3306);
// Forma actual, la que uso siempre
$config = ['host' => 'localhost', 'port' => 3306];
// Sin claves explícitas: PHP asigna 0, 1, 2...
$colores = ['rojo', 'verde', 'azul'];
// Mezclando: PHP rellena los índices que faltan
$mixto = ['a' => 1, 2, 'b' => 3, 4];
// => ['a' => 1, 0 => 2, 'b' => 3, 1 => 4]
Fíjate en el último ejemplo: sí, puedes mezclar claves de texto y numéricas en el mismo array, precisamente porque es un mapa y le da igual. Los valores sin clave explícita reciben el siguiente entero disponible, que se calcula a partir de la clave entera más alta usada hasta ese momento.
Para añadir elementos después:
$usuario = [];
$usuario['nombre'] = 'Ada'; // clave explícita
$usuario['roles'][] = 'admin'; // crea el subarray y empuja
$colores[] = 'amarillo'; // empuja al final con la siguiente clave int
El [] vacío como destino de asignación es el "push": añade al final con la siguiente clave entera. No lo confundas con leer $array[], que es un error de sintaxis: [] solo vale para escribir.
Recorrer un array con foreach: clave y valor
foreach es la herramienta que usas casi siempre, y su forma completa expone las dos partes del par:
La sintaxis clave => valor no es exclusiva de los "arrays asociativos": funciona igual sobre una lista, donde la clave es el índice entero. Quien busca cómo usar foreach en PHP casi siempre necesita justo esto y recorrer estructuras anidadas, así que voy con lo segundo:
Un foreach anidado por nivel. Nada más. Si te encuentras con tres o cuatro niveles de anidamiento y foreach dentro de foreach dentro de foreach, eso no es un problema de sintaxis: es una señal de que esos arrays deberían haber sido objetos, y a eso llego al final.
La trampa del foreach por referencia (&$valor) que duplica el último elemento
Este es el bug de arrays que más veces he visto en revisiones ajenas, y casi nunca lo pilla quien lo escribió. Cuando quieres modificar el array mientras lo recorres, usas una referencia con &:
$precios = [10, 20, 30];
foreach ($precios as &$precio) {
$precio *= 1.21; // aplico IVA in situ
}
// $precios ahora es [12.1, 24.2, 36.3] correcto hasta aquí
Hasta aquí, bien. El problema es lo que pasa después, si reutilizas el array. Tras ese bucle, la variable $precio sigue siendo una referencia viva al último elemento de $precios. No desaparece al salir del foreach. Y en cuanto vuelvas a usar $precio, o hagas otro foreach con el mismo nombre de variable, escribes sobre el último elemento del array sin querer:
$precios = [10, 20, 30];
foreach ($precios as &$precio) { /* ... */ } // $precio apunta a $precios[2]
foreach ($precios as $precio) { /* nada */ }
// En cada vuelta, $precio se ASIGNA... y como es una referencia a $precios[2],
// estás sobrescribiendo el último elemento con cada valor que recorres.
// Resultado final: [10, 20, 20] <- el penúltimo valor se cuela en el último
Ese [10, 20, 20] es el clásico "se me duplica el último elemento". No es un fallo del intérprete: es exactamente lo que le has pedido. El propio manual, en el ejemplo oficial, deja el aviso: hay que hacer unset() de la variable en cuanto acabas el bucle por referencia.
foreach ($precios as &$precio) {
$precio *= 1.21;
}
unset($precio); // rompe la referencia colgante. SIEMPRE, sin excepción.
Mi regla, después de tropezar con esto más de una vez: si escribes & en un foreach, la línea siguiente es unset(). Sin pensarlo. Y si puedes evitar la referencia entera, reconstruyendo el array con array_map, por ejemplo, mejor todavía; el código por referencia es más difícil de razonar de lo que compensa.
Un array en PHP no es una lista ni un diccionario: es un mapa ordenado. Toda su rareza sale de ahí.
Conversión silenciosa de claves: cuando "1", true y null te machacan datos
Las claves solo pueden ser int o string, así que cuando pasas cualquier otra cosa como clave, PHP la convierte. Casi siempre lo hace en silencio, siguiendo reglas que poca gente tiene en la cabeza (php.net):
Escribes como clave
Se almacena como
Nota
"8"
8 (int)
Un string con un entero decimal válido pasa a int
"08"
"08" (string)
No es decimal válido (cero a la izquierda): se queda string
8.7
8 (int)
Se trunca, no se redondea. Desde PHP 8.1 emite un Deprecated
true
1 (int)
false
0 (int)
null
"" (string)
Cadena vacía
"1abc"
"1abc" (string)
No es entero puro: se queda string
El float es la única de esas conversiones que avisa. Las demás son mudas, y ahí está el peligro: la colisión. Dos claves que tú ves distintas acaban siendo la misma, y la segunda pisa a la primera sin que nada se queje:
$mapa = [
1 => 'entero',
'1' => 'string uno', // "1" -> 1, PISA a la anterior
true => 'booleano', // true -> 1, PISA otra vez
1.9 => 'float', // 1.9 -> 1, y otra (esta sí avisa: Deprecated)
null => 'nulo', // null -> "", esta sí es una clave nueva
];
var_export($mapa);
// [1 => 'float', '' => 'nulo'] <- de cinco entradas quedan DOS
De cinco pares, sobreviven dos. Esto muerde de verdad cuando construyes un array indexado por un valor que crees único, un ID que llega como string de una API, un flag booleano, una clave calculada, y silenciosamente pierdes filas. Si necesitas que 1 y "1" convivan como claves distintas, un array no te sirve: usa un SplObjectStorage, un Map de una librería de estructuras de datos, o reconsidera el modelo. El array no te va a proteger de esto porque, para él, no hay dos claves.
isset() frente a array_key_exists(): la diferencia con valores null
Para comprobar si una clave existe, la mano va sola a isset(). Y funciona… hasta que el valor guardado es null. Porque isset() no responde "¿existe la clave?", responde "¿existe la clave Y su valor no es null?". Son preguntas distintas.
La distinción no es académica. Imagina un formulario donde null significa "el usuario dejó el campo en blanco a propósito" y la ausencia de clave significa "el campo no venía en el envío". Son casos de negocio diferentes, y isset() los aplasta en el mismo false. Si te ha mordido alguna vez la lógica de tres valores de una base de datos, esto es primo hermano de aquello: lo conté en detalle en por qué NULL no es menor que una fecha, y el patrón mental es idéntico: null no es "vacío", es "no lo sé".
Regla práctica: usa isset() cuando de verdad quieras "existe y tiene valor útil" (que es lo más común y además es más rápido). Usa array_key_exists() cuando la existencia de la clave es en sí misma la información, con valores null legítimos de por medio. El operador de fusión de null, ??, se comporta como isset(): también trata null como "no está".
Ordenar sin perder las claves: asort, ksort y uasort frente a sort
Aquí es donde entender que todo es un mapa ordenado te ahorra un bug clásico: sort() reindexa. Tira tus claves y las reemplaza por 0, 1, 2.... Sobre una lista da igual; sobre un array asociativo es una catástrofe silenciosa.
$edades = ['Ana' => 34, 'Leo' => 28, 'Zoe' => 41];
sort($edades);
// [0 => 28, 1 => 34, 2 => 41] <- perdiste los nombres. Un desastre.
asort($edades);
// ['Leo' => 28, 'Ana' => 34, 'Zoe' => 41] <- ordena por valor, conserva claves ```
El mapa de funciones de ordenación, que conviene tener claro de una vez:
| Función | Ordena por | ¿Conserva claves? |
|---|---|---|
| `sort` / `rsort` | valor | No (reindexa) |
| `asort` / `arsort` | valor | Sí |
| `ksort` / `krsort` | clave | Sí |
| `usort` | valor (callback) | No (reindexa) |
| `uasort` | valor (callback) | Sí |
| `uksort` | clave (callback) | Sí |
La regla mnemotécnica: la `a` es de "asociativo, mantiene claves", la `k` es de "key", la `u` es de "user callback". Todas ordenan el array **por referencia** y devuelven `bool`, no el array ordenado; un error frecuente es escribir `$x = sort($x)` y quedarte con `true`. Para ordenar por un criterio compuesto, por ejemplo, una lista de personas por edad y a igualdad de edad por nombre, `usort` con una función es lo que uso:
```php
$personas = [
['nombre' => 'Zoe', 'edad' => 30],
['nombre' => 'Ana', 'edad' => 30],
['nombre' => 'Leo', 'edad' => 25],
];
usort($personas, fn($a, $b) => [$a['edad'], $a['nombre']] <=> [$b['edad'], $b['nombre']]);
// Leo(25), Ana(30), Zoe(30)
El operador nave espacial <=> comparando dos arrays hace el desempate en cascada por ti: compara el primer elemento, y solo si empatan pasa al segundo. Aquí usort reindexa, cosa que casi siempre quieres en una lista.
Las funciones de array que de verdad uso
El manual tiene decenas. En el día a día vuelvo a las mismas seis, casi siempre para no escribir un foreach con una variable acumuladora al lado.
$productos = [
['id' => 1, 'nombre' => 'Teclado', 'precio' => 45, 'activo' => true],
['id' => 2, 'nombre' => 'Ratón', 'precio' => 25, 'activo' => false],
['id' => 3, 'nombre' => 'Monitor', 'precio' => 180, 'activo' => true],
];
// array_map: transforma cada elemento
$nombres = array_map(fn($p) => $p['nombre'], $productos);
// ['Teclado', 'Ratón', 'Monitor']
// array_filter: se queda con los que cumplen (ojo con las claves, ver siguiente sección)
$activos = array_filter($productos, fn($p) => $p['activo']);
// array_reduce: colapsa la lista en un valor
$total = array_reduce($productos, fn($acc, $p) => $acc + $p['precio'], 0);
// 250
// array_column: extrae una columna, opcionalmente indexada por otra
$precioPorId = array_column($productos, 'precio', 'id');
// [1 => 45, 2 => 25, 3 => 180]
// array_combine: dos listas (claves, valores) -> un mapa
$cabeceras = array_combine(['a', 'b', 'c'], [1, 2, 3]);
// ['a' => 1, 'b' => 2, 'c' => 3]
array_column es de las más infravaloradas: convierte una lista de filas (típico resultado de una consulta) en el índice que necesitas sin un bucle. array_combine exige que ambas listas tengan la misma longitud o lanza un ValueError en PHP 8, así que valida antes. Y array_reduce es la que la gente evita por costumbre y la que más claridad da cuando lo que quieres es un único valor a partir de una colección: un total, una concatenación, un máximo.
array_filter conserva las claves (y por qué necesitas array_values después)
array_filter tiene una particularidad que rompe más JSON de lo que debería: conserva las claves originales del array. Si filtras una lista y eliminas elementos del medio, las claves dejan de ser consecutivas (php.net).
Sobre un array asociativo eso es justo lo que quieres. Pero si esa lista filtrada la conviertes a JSON esperando un array [...], te llevas una sorpresa:
echo json_encode($pares); // {"1":20,"3":40} <- ¡un objeto, no un array!
echo json_encode(array_values($pares)); // [20,40] <- ahora sí, un array
json_encode decide entre [] y {} mirando si las claves son 0, 1, 2... consecutivas. Un array con huecos se serializa como objeto, y ahí tienes tu frontend recibiendo {"1": ...} cuando esperaba una lista. La cura es una línea: array_values() reindexa y descarta las claves. Mi hábito es encadenarlo siempre que filtro algo que va a viajar como lista: array_values(array_filter($lista, $criterio)). Si lo que filtras es un mapa de verdad, no lo hagas: perderías las claves que necesitas.
Unir arrays: array_merge frente al operador + (y por qué + no reindexa)
Dos formas de combinar arrays, y hacen cosas distintas. La confusión entre ellas es una fuente estupenda de bugs.
array_merge($a, $b): en claves de string, las de $b sobrescriben las de $a. En claves enteras, no sobrescribe: renumera y concatena todo.
El operador + (unión): conserva las claves de $a y solo añade de $b las claves que $ano tenía. No renumera nunca, no sobrescribe nunca.
$a = ['x' => 1, 'y' => 2];
$b = ['y' => 99, 'z' => 3];
array_merge($a, $b); // ['x' => 1, 'y' => 99, 'z' => 3] <- y de $b gana
$a + $b; // ['x' => 1, 'y' => 2, 'z' => 3] <- y de $a se queda
// Con claves enteras, la diferencia es brutal:
$c = ['a', 'b']; // [0 => 'a', 1 => 'b']
$d = ['c', 'd']; // [0 => 'c', 1 => 'd']
array_merge($c, $d); // ['a', 'b', 'c', 'd'] <- renumera: 0,1,2,3
$c + $d; // ['a', 'b'] <- 0 y 1 ya existían en $c, ignora $d
Ese último caso pilla a todo el mundo: $c + $d te devuelve ['a', 'b'] y pierdes $d entero, porque sus claves 0 y 1 ya existían en $c. Regla que uso: array_merge para listas (quiero concatenar y renumerar) y para mapas donde el segundo debe ganar; el operador + solo para aplicar valores por defecto a un array de configuración, que es exactamente su caso ideal: $opciones = $opcionesUsuario + $porDefecto; mantiene lo que puso el usuario y rellena lo que faltaba.
in_array con comparación laxa: el agujero que PHP 8 corrigió
in_array($aguja, $pajar) por defecto compara con ==, la comparación laxa. En PHP 7 y anteriores, eso abría un agujero de seguridad tan famoso como peligroso:
¿Por qué? Porque 'abc' == 0 era true en PHP 7: al comparar un string no numérico con un entero, PHP convertía el string a número, y 'abc' se volvía 0. Resultado: cualquier cadena de texto "coincidía" con un 0 en el array. Si usabas eso para comprobar permisos, "¿está este token en la lista blanca?", con un 0 traspapelado en la lista, dejabas pasar cualquier cosa.
PHP 8 cambió las reglas de comparación no estricta: ahora, al comparar un número con un string no numérico, se convierte el número a string, no al revés (php.net). Así 0 == 'abc' pasó de true a false, y con ello in_array('abc', [0]) devuelve por fin false.
// PHP 8+
in_array('abc', [0]); // false 0 == 'foo'; // false (en PHP 7 era true)
0 == ''; // false (en PHP 7 era true)
0 == '0'; // true (esto no cambia: '0' sí es numérico)
No confíes en la versión del intérprete para tu seguridad. La solución correcta, en cualquier versión, es el tercer parámetro de in_array, que activa la comparación estricta ===:
in_array('abc', [0], true); // false SIEMPRE, en PHP 5, 7 y 8
in_array('0', [0], true); // false: distinto tipo, no coincide
Mi norma es tajante: in_array y array_searchsiempre con true salvo que tenga una razón concreta y consciente para querer la laxa. El coste de escribir , true es cero; el coste de olvidarlo puede ser una autenticación rota.
Spread (...) y desestructuración de arrays
Dos azucarillos de sintaxis modernos que uso a diario. El operador de propagación ... expande un array dentro de otro literal:
Con claves enteras funciona desde PHP 7.4; con claves de string, desde PHP 8.1. Y ojo, porque el desempaquetado sigue la misma semántica que array_merge: las claves de string posteriores sobrescriben a las anteriores, y las enteras se renumeran (php.net).
$a = ['nombre' => 'Ada'];
$b = ['nombre' => 'Leo', 'rol' => 'admin'];
$c = [...$a, ...$b]; // ['nombre' => 'Leo', 'rol' => 'admin'] <- b gana, como en array_merge
La desestructuración va en dirección contraria: saca valores de un array a variables. Con [] a la izquierda del =:
['nombre' => $nombre, 'edad' => $edad] = ['nombre' => 'Ada', 'edad' => 34];
echo $nombre; // Ada
// Por posición, y saltando elementos con comas:
[$primero, , $tercero] = ['a', 'b', 'c'];
echo $tercero; // c
// Brilla dentro de un foreach sobre filas:
foreach ($productos as ['nombre' => $n, 'precio' => $p]) {
echo "{$n}: {$p}€\n";
}
Esa última forma, desestructurar en la propia cabecera del foreach, deja el bucle mucho más legible que ir picando $fila['nombre'] en cada línea. Es de las cosas que más limpian el código de manejo de datos.
Rendimiento y memoria: cómo funciona el copy-on-write
Los arrays de PHP se asignan y se pasan a funciones por valor, no por referencia. En teoría eso significa copiar todo el array cada vez, lo cual asustaría con arrays grandes. En la práctica no pasa, gracias a un mecanismo llamado copy-on-write (COW): al asignar $b = $a, PHP no duplica los datos, solo apunta a la misma zona de memoria y lleva un contador de referencias. La copia real solo ocurre en el momento en que uno de los dos se modifica.
$grande = range(1, 1_000_000); // ocupa memoria una vez
$copia = $grande; // NO duplica: mismo buffer, refcount = 2
$copia[0] = -1; // AQUÍ sí copia: ahora hay dos buffers
La consecuencia práctica: leer una copia es gratis, escribirla cuesta. Y hay una trampa relacionada con lo que expliqué antes: recorrer por referencia (&) fuerza a PHP a mantener el array "modificable" y puede impedir que comparta memoria. Para el 99% de los casos no necesitas pensar en esto; los arrays de PHP son eficientes de sobra. Pero cuando manejas cientos de miles de filas y la memoria empieza a apretar, dos cosas ayudan de verdad: no acumular el dataset entero en un array si puedes procesarlo en streaming con un generador (yield), y evitar duplicar sin querer arrays enormes pasándolos por referencia explícita cuando tenga sentido. Antes de optimizar nada, mide con memory_get_peak_usage(); casi siempre el cuello de botella está en otro sitio.
Cuándo un array debería haber sido un objeto
Termino con lo que más código me ha ahorrado a largo plazo, y no es una función. El array asociativo es tan cómodo que se convierte en el martillo con el que todo parece un clavo: lo uso como registro, como DTO, como objeto de configuración, como valor de retorno con diez claves. Y ahí empieza la deuda.
El síntoma es claro. Si te encuentras escribiendo $pedido['cliente']['direccion']['codigo_postal'] y rezando para que todas las claves existan, o repartiendo $usuario['email'] por veinte ficheros sin ninguna garantía de que la clave se llame así en todos, ese array pide a gritos ser una clase. Un objeto te da tres cosas que el array nunca dará: un contrato explícito (las propiedades tipadas dicen qué hay y de qué tipo), autocompletado real en el editor, y un único sitio donde validar. Con PHP moderno, un DTO cuesta cuatro líneas:
final class DireccionEnvio
{
public function __construct(
public readonly string $calle,
public readonly string $codigoPostal,
public readonly string $ciudad,
) {}
}
Ahora un typo en codigoPostal es un error en tu editor, no un null silencioso en producción tres semanas después. Mi criterio, después de más de veinte años, es simple: el array es perfecto para colecciones homogéneas, una lista de cosas del mismo tipo que vas a recorrer, y para datos de forma desconocida o cambiante. En cuanto una estructura tiene claves fijas y conocidas que se leen en más de un sitio, deja de ser un array y pasa a ser un objeto. Ese es, para mí, el conocimiento que separa un tutorial de arrays de saber usarlos de verdad; si quieres, tengo más sobre cómo enfoco la arquitectura y los estándares con los que trabajo.
Los arrays de PHP son una de las estructuras de datos más versátiles de cualquier lenguaje. Justo por eso conviene conocer sus bordes: la conversión de claves, el foreach por referencia, la diferencia entre + y array_merge, y el momento en que dejan de ser la herramienta correcta. Eso es lo que no te cuenta el ejemplo de "hola mundo con arrays", y es lo que evita los bugs que no dan la cara.
Preguntas frecuentes
¿Por qué el foreach por referencia me duplica el último elemento del array?
Porque al terminar un foreach ($array as &$valor), la variable $valor sigue siendo una referencia viva al último elemento del array. No se destruye al salir del bucle. Si después reutilizas esa variable, por ejemplo, en otro foreach con el mismo nombre, cada asignación sobrescribe el último elemento del array. El resultado típico es que el penúltimo valor acaba copiado en el último. La solución es hacer unset($valor) justo después del bucle por referencia, siempre, sin excepción.
¿Cuál es la diferencia entre isset() y array_key_exists()?
isset() responde a "¿existe la clave Y su valor no es null?"; devuelve false si la clave no existe o si existe pero vale null. array_key_exists() responde solo a "¿existe la clave?", sin importar su valor, así que devuelve true aunque el valor sea null. Usa isset() (o el operador ??) cuando quieras "existe y tiene valor útil", que es lo más común y más rápido. Usa array_key_exists() cuando distingas entre "la clave no está" y "la clave está pero es null", dos casos que isset aplasta en el mismo false.
¿Cómo ordeno un array asociativo sin perder las claves?
No uses sort(): reindexa y sustituye tus claves por 0, 1, 2... Para conservar la asociación clave-valor tienes asort() y arsort() (ordenan por valor), ksort() y krsort() (ordenan por clave) y sus versiones con callback uasort() y uksort(). La regla mnemotécnica: la a indica "asociativo, mantiene claves", la k es "key" y la u es "user callback". Todas ordenan por referencia y devuelven un booleano, así que no escribas $x = asort($x).
¿Qué diferencia hay entre array_merge y el operador + en PHP?
array_merge($a, $b) sobrescribe las claves de string de $a con las de $b, y en las claves enteras renumera y concatena todo. El operador + conserva las claves de $a y solo añade de $b las claves que $a no tenía: nunca sobrescribe ni renumera. Por eso ['a','b'] + ['c','d'] devuelve ['a','b'] (las claves 0 y 1 ya existían). Usa array_merge para concatenar listas o cuando el segundo array debe ganar; usa + para aplicar valores por defecto a una configuración.
¿Por qué array_filter deja huecos en los índices del array?
Porque array_filter conserva las claves originales del array. Si eliminas elementos del medio de una lista, las claves supervivientes dejan de ser consecutivas (por ejemplo, quedan 1 y 3). Sobre un array asociativo eso es lo deseable, pero si esa lista la conviertes a JSON, json_encode la serializa como objeto {"1":...} en vez de como array [...], porque las claves no son 0,1,2 consecutivas. La cura es una línea: envuelve el resultado en array_values() para reindexar antes de que la lista viaje.
¿Cuándo conviene usar un objeto o DTO en lugar de un array?
El array es ideal para colecciones homogéneas que vas a recorrer y para datos de forma desconocida o cambiante. En cuanto una estructura tiene claves fijas y conocidas que se leen en más de un sitio, un pedido, un usuario, una dirección, pasa a ser un objeto o un DTO. Un objeto te da un contrato explícito con propiedades tipadas, autocompletado real en el editor y un único punto de validación. Así un error al escribir una clave se convierte en un fallo visible en el editor, no en un null silencioso en producción.
date() es lo que todos buscan para trabajar con fechas en PHP y casi nunca lo correcto. Te enseño date() y strtotime() para leer código ajeno, y por qué DateTimeImmutable, UTC y diff() evitan los errores que cuestan dinero.
Las comillas simples no son una cuestión de estilo. En PHP interpolan o no, en SQL separan un dato de un nombre de tabla, y confundirlas abre la puerta a la inyección. Guía por lenguaje, con los casos límite que rompen el código.
Qué puedes automatizar de verdad con IA hoy y qué no, sin humo. Dónde un modelo de lenguaje es la herramienta correcta, dónde es un peligro, y cómo se monta para que aguante en producción.
¿Te ha servido?
Si tienes un problema parecido y quieres una opinión técnica, cuéntamelo. Te respondo en menos de 24 h laborables.
Uso cookies propias necesarias para que la web funcione. Las demás categorías
están desactivadas hasta que tú decidas. Puedes aceptarlas todas, rechazarlas
todas o elegir una a una. Más detalle en la
política de cookies.