in_array, array_search y array_key_exists en PHP: buscar en arrays sin errores

Buscar un valor o una clave en un array es de las operaciones más frecuentes en PHP, y las tres funciones principales tienen diferencias que generan bugs si no las conoces bien. in_array() busca un valor, array_search() devuelve la clave donde está ese valor, y array_key_exists() comprueba si una clave concreta existe. La trampa está en la comparación débil por defecto y en la diferencia entre isset() y array_key_exists() cuando el valor es null.

in_array(): existe este valor en el array

<?php
$roles = ['admin', 'editor', 'lector'];

// Sin strict: usa comparación débil (==)
var_dump(in_array('admin', $roles));   // bool(true)
var_dump(in_array('Admin', $roles));   // bool(false) - sí distingue mayúsculas
var_dump(in_array(0, $roles));         // bool(true) ? TRAMPA: 0 == 'admin' en PHP 7
                                       // bool(false) en PHP 8 (comportamiento cambiado)

// Con strict: usa comparación estricta (===)
var_dump(in_array(0, $roles, true));   // bool(false) - correcto en PHP 7 y 8
?>

Pasa siempre true como tercer argumento cuando el array puede contener mezcla de strings y números. Es un bug histórico que PHP 8 mitiga parcialmente pero no elimina del todo.

La trampa clásica con comparación débil

<?php
$permisosNumericos = [0, 1, 2]; // 0=ninguno, 1=leer, 2=escribir

// PHP 7: in_array('admin', [0, 1, 2]) devuelve TRUE porque 'admin' == 0
// Esto significa que un usuario sin permisos pasaría la comprobación
if (in_array('admin', $permisosNumericos)) { // BUG en PHP 7
    echo "Tiene permiso"; // Se ejecuta cuando NO debería
}

// Correcto: usar strict
if (in_array('admin', $permisosNumericos, true)) {
    echo "Tiene permiso"; // No se ejecuta
}
?>

array_search(): obtener la clave, no solo true/false

<?php
$idiomas = ['es' => 'Español', 'en' => 'English', 'fr' => 'Français'];

$clave = array_search('English', $idiomas);
var_dump($clave); // string(2) "en"

// Si no encuentra nada devuelve false
$no_existe = array_search('Deutsch', $idiomas);
var_dump($no_existe); // bool(false)

// Comprobación estricta para evitar el problema con clave 0
$posicion = array_search('Español', $idiomas);
if ($posicion !== false) { // === o !== para no confundir con clave '0' o 0
    echo "Encontrado en: $posicion";
}
?>

array_key_exists() vs isset(): la diferencia con null

Esta es la diferencia que más sorprende: isset() devuelve false para claves con valor null; array_key_exists() devuelve true porque la clave sí existe, aunque su valor sea null:

<?php
$config = [
    'host'     => 'localhost',
    'password' => null,  // explícitamente nulo (sin contraseña)
    'puerto'   => 3306,
];

var_dump(isset($config['password']));             // bool(false) ? INCORRECTO si quieres saber si existe
var_dump(array_key_exists('password', $config));  // bool(true)  ? correcto

var_dump(isset($config['timeout']));              // bool(false)
var_dump(array_key_exists('timeout', $config));   // bool(false)
?>

Búsquedas O(1) con array_flip para arrays grandes

<?php
$idsVip = [102, 458, 873, 1204, 3891]; // puede ser un array de miles de IDs

// Forma lenta: O(n) en cada llamada
function esVipLento(int $id, array $vips): bool
{
    return in_array($id, $vips, true);
}

// Forma rápida: invertir una vez y buscar por clave O(1)
$mapaVip = array_flip($idsVip);
function esVipRapido(int $id, array $mapa): bool
{
    return isset($mapa[$id]);
}

var_dump(esVipRapido(458, $mapaVip));  // bool(true)
var_dump(esVipRapido(999, $mapaVip));  // bool(false)
?>

La documentación oficial de in_array() incluye las notas sobre los cambios de comparación entre PHP 7 y PHP 8, especialmente con valores numéricos en strings.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP