Menu

Preguntas de entrevista de PHP con respuestas (PHP 8)

24 preguntas de entrevista de PHP con respuestas cortas y correctas para PHP 8, desde == frente a === e isset frente a empty hasta las referencias en foreach, self frente a static, los generadores, la inyección SQL y el hash de contraseñas. La mayoría de las respuestas tienen código que puedes ejecutar y cambiar.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Estas son las preguntas de PHP que más salen en las entrevistas, con respuestas cortas que son correctas para PHP 8.3 y código donde el código lo deja claro. Predice la salida de cada bloque antes de pulsar Ejecutar: eso es lo que evalúa un entrevistador.

Preguntas de entrevista de PHP de nivel básico

¿Qué es PHP y cómo se ejecuta?

PHP es un lenguaje de scripting del lado del servidor. Un servidor web (Nginx o Apache) pasa la petición a PHP (normalmente PHP-FPM), PHP ejecuta el script desde arriba, y lo que imprime se convierte en la respuesta, normalmente HTML. Cada petición empieza de cero: las variables no sobreviven entre peticiones salvo que las guardes en una sesión, una base de datos o una caché. PHP también ejecuta scripts en la línea de comandos (php script.php).

¿Cuál es la diferencia entre == y ===?

== compara después de la conversión de tipos y === compara valor y tipo sin conversión. El calentamiento de arriba muestra == en acción: las cadenas numéricas se comparan como números, así que '10' == '1e1' es true. Desde PHP 8, un número comparado con una cadena no numérica se compara como cadena, así que 0 == 'a' es false (en PHP 7 era true). Toca las celdas para comparar los dos operadores:

Comparación flexible (==) y estricta (===)
Point at or tap a cell to read it as PHP.
$a == $btruefalse01"0""1"""null[]"a""10""1e1"
true
false
0
1
"0"
"1"
""
null
[]
"a"
"10"
"1e1"
Every cell computed by PHP 8.3.19.

Usa === por defecto. in_array() y array_search() usan == salvo que pases true como tercer argumento.

¿Cuál es la diferencia entre echo y print?

Los dos imprimen cadenas. echo acepta varios argumentos (echo $a, $b;) y no devuelve nada; print acepta uno y devuelve 1, así que se puede usar en una expresión. Ninguno es una función, así que los paréntesis son opcionales. En la práctica todo el mundo usa echo.

¿Comillas simples o comillas dobles?

Las cadenas entre comillas dobles interpolan variables y secuencias de escape: "Hi $name\n". Las cadenas entre comillas simples son literales salvo \' y \\: 'Hi $name\n' imprime exactamente esos caracteres. La diferencia de velocidad es despreciable, así que la elección es de legibilidad: comillas dobles cuando interpolas y simples cuando no.

¿Cuáles son los tipos de datos de PHP?

Cuatro tipos escalares (int, float, string, bool), dos compuestos (array y object) y dos especiales (null y resource). callable, iterable, mixed y void solo existen como declaraciones de tipo, nunca como tipo de un valor. gettype() y get_debug_type() te dicen el tipo de un valor en tiempo de ejecución, y var_dump() lo imprime junto con el valor.

¿Cuál es la diferencia entre isset, empty e is_null?

isset($x) es true cuando la variable existe y no es null. empty($x) es true cuando la variable no existe o es falsy (0, '0', '', [], false, null). is_null($x) es true para null, pero avisa con una variable no definida. isset y empty nunca avisan, y por eso se usan con las claves de array.

isset, empty e is_null para cada valor de $x
Point at or tap a cell to read it as PHP.
$xissetemptyis_null
null
false
0
"0"
""
" "
[]
"a"
0.0
Every cell computed by PHP 8.3.19.

La fila en la que la gente se equivoca es "0": la cadena cero está vacía, mientras que " " (un espacio) no. La página de isset tiene la tabla completa.

¿Cuál es la diferencia entre include y require?

Los dos insertan y ejecutan otro archivo. Si falta el archivo, include emite un warning y el script continúa, mientras que require lanza un Error ("Failed opening required"), que detiene el script salvo que algo lo capture. Las variantes _once (include_once, require_once) se saltan un archivo que ya se cargó, lo que evita los errores "cannot redeclare function". Usa require (o require_once) para los archivos sin los que el script no puede funcionar, que son casi todos; el autoloader de Composer hace innecesarios la mayoría de los includes manuales.

¿Cuál es la diferencia entre GET y POST?

GET envía los datos en la query string de la URL ($_GET), así que son visibles, se pueden guardar en favoritos y tienen una longitud limitada; úsalo para leer, como búsquedas y paginación. POST envía los datos en el cuerpo de la petición ($_POST); úsalo para todo lo que cambia el estado, como iniciar sesión, guardar o pagar. Una petición GET nunca debería cambiar datos, porque los enlaces se precargan y se rastrean.

¿Qué es el operador de fusión de null?

$a ?? $b devuelve $a si existe y no es null, y si no $b, sin warning por una variable o clave no definida: $page = $_GET['page'] ?? 1;. ??= asigna solo cuando el lado izquierdo es null o falta. Se diferencia de ?:, que usa el valor por defecto con cualquier valor falsy, así que 0 ?: 5 es 5 pero 0 ?? 5 es 0.

Preguntas de entrevista de PHP de nivel intermedio

¿Qué pasa cuando recorres por referencia en foreach?

foreach ($arr as &$v) te permite modificar los elementos en el sitio, pero $v sigue siendo una referencia al último elemento después del bucle. Reutilizar el nombre en un segundo bucle sobrescribe entonces ese elemento:

El último elemento es 20, no 30: durante el segundo bucle, a $v (que sigue siendo $arr[2]) se le asigna 10, luego 20 y luego a sí mismo. Quita el // delante de unset($v) y vuelve a ejecutarlo. La página de foreach explica las referencias en detalle.

¿Cuál es la diferencia entre una clase abstracta y una interfaz? ¿Y qué es un trait?

Una interfaz es un contrato: firmas de métodos (y constantes) sin implementación, y una clase puede implementar muchas. Una clase abstracta puede contener propiedades, constructores y métodos terminados, además de métodos abstractos que sus hijas deben escribir; una clase solo extiende una. Un trait es un conjunto de métodos que se copia en una clase con use, para reutilizar código entre clases que no comparten un padre.

Una respuesta corta que gusta a los entrevistadores: usa una interfaz para decir qué puede hacer algo, una clase abstracta para compartir cómo se hace y un trait cuando clases no relacionadas necesitan los mismos pocos métodos.

¿Cuál es la diferencia entre self y static?

self se refiere a la clase donde está escrito el código. static se refiere a la clase a la que realmente se llamó en tiempo de ejecución, lo que se llama late static binding. Importa en los métodos del padre que crean o describen "este tipo de objeto":

User::createStatic() construye un User. User::createSelf() construye un Model, lo que rompe el tipo de retorno static, así que PHP lanza un TypeError. Por eso los métodos factoría usan new static().

¿Qué son los métodos mágicos?

Métodos que PHP llama por ti, todos empiezan por dos guiones bajos. Los habituales: __construct() cuando se crea un objeto, __destruct() cuando se destruye, __toString() cuando se usa como cadena, __get() y __set() para propiedades inaccesibles, __call() y __callStatic() para métodos que no existen, __invoke() cuando el objeto se llama como una función y __clone() después de clone.

¿Cuál es la diferencia entre array_merge() y el operador +?

array_merge() añade: las claves numéricas se renumeran y las claves de texto posteriores sobrescriben a las anteriores. + es una unión: conserva el array izquierdo y solo añade las claves que faltan, así que con una clave duplicada gana el primer valor.

+ es la herramienta adecuada para los valores por defecto: $options + ['timeout' => 30] conserva lo que pasó quien llama y rellena el resto.

¿Qué hace declare(strict_types=1)?

Sin él, PHP convierte los argumentos escalares al tipo declarado del parámetro cuando puede: pasar "5" a un parámetro int da 5. Con declare(strict_types=1); como primera sentencia de un archivo, las llamadas hechas desde ese archivo deben pasar el tipo exacto; si no, se lanza un TypeError (un int pasado a un parámetro float es la única ampliación permitida).

Borra la línea declare y vuelve a ejecutarlo: la segunda llamada devuelve 10 en lugar de lanzar un error.

Una cookie se guarda en el navegador y se envía con cada petición, así que el visitante puede leerla y cambiarla. Una sesión guarda los datos en el servidor y solo mantiene un id aleatorio en una cookie (PHPSESSID). Pon en $_SESSION todo lo que deba ser de confianza, como el id del usuario que ha iniciado sesión; después de iniciar sesión, llama a session_regenerate_id(true). La página de sesiones y cookies tiene el código.

¿Cómo se evita la inyección SQL?

Nunca construyas SQL concatenando la entrada. Usa sentencias preparadas, para que los valores se envíen separados de la consulta:

<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
$user = $stmt->fetch();

Los marcadores solo sirven para valores. Los nombres de tablas, los nombres de columnas y ASC/DESC deben comprobarse contra una lista permitida antes de ponerlos en el SQL. Consulta PDO.

¿Cómo se evita el XSS?

Escapa la salida, no la entrada: envuelve cada valor que imprimas en HTML en htmlspecialchars($value, ENT_QUOTES, 'UTF-8'), o usa un motor de plantillas que lo haga automáticamente (Twig, Blade). Dentro de <script>, usa json_encode() con JSON_HEX_TAG. Añade una cabecera Content-Security-Policy como segunda capa.

¿Cómo deben guardarse las contraseñas?

Con password_hash($password, PASSWORD_DEFAULT), y se comprueban con password_verify($password, $hash). Usan bcrypt (o Argon2id) con una sal aleatoria guardada dentro del hash y un coste deliberado. md5() y sha1() no sirven para contraseñas porque son rápidos y sin sal. Usa password_needs_rehash() al iniciar sesión para actualizar los hashes antiguos.

Preguntas de entrevista de PHP de nivel avanzado

¿Qué son los generadores y cuándo usarías uno?

Una función que contiene yield devuelve un Generator que produce valores de uno en uno, solo cuando se le piden. Te permite recorrer una secuencia grande o infinita sin construir un array en memoria:

Los usos típicos son leer un archivo grande línea a línea, enviar filas de una base de datos en streaming y los pipelines perezosos. Los generadores también admiten claves (yield $key => $value), delegación (yield from) y recibir valores con send().

¿Qué son los closures y qué hace use?

Una función anónima (function () { ... }) es un objeto Closure. No ve las variables de fuera salvo que las listes en use, que copia el valor en el momento en que se crea el closure; use (&$x) captura por referencia. Las funciones flecha (fn ($x) => $x * $factor) capturan automáticamente las variables de fuera, por valor, y contienen una sola expresión.

¿Cuál es la diferencia entre abstract, final y readonly?

abstract marca una clase que no se puede instanciar, o un método que una hija debe implementar. final prohíbe sobrescribir un método o extender una clase. readonly (PHP 8.1) hace que una propiedad solo se pueda escribir una vez, desde dentro de la clase, normalmente en el constructor; PHP 8.2 añadió las clases readonly, en las que todas las propiedades son readonly.

¿Qué es Composer y qué es PSR-4?

Composer es el gestor de dependencias de PHP: composer.json enumera los paquetes, composer.lock fija las versiones exactas y vendor/autoload.php lo carga todo. PSR-4 es el estándar de autoloading que asigna un prefijo de namespace a una carpeta, así que App\Mail\Mailer está en src/Mail/Mailer.php y se carga en el primer uso. Explica install (desde el archivo lock) frente a update (versiones nuevas, archivo lock nuevo).

¿Qué cambió en PHP 8?

Las funciones principales: en la 8.0, argumentos con nombre, match, el operador nullsafe ?->, tipos unión, promoción de propiedades en el constructor, atributos, str_contains() y una comparación entre cadenas y números más sensata; en la 8.1, enums, propiedades readonly, la sintaxis de callable de primera clase (strlen(...)) y los fibers; en la 8.2, clases readonly y los tipos independientes null/true/false; en la 8.3, constantes de clase tipadas, el atributo #[\Override] y json_validate(); en la 8.4, property hooks, visibilidad asimétrica (public private(set)), array_find() y new Foo()->method() sin paréntesis alrededor. Además, muchas funciones lanzan ahora TypeError o ValueError en lugar de devolver false con un warning.

¿Cómo gestiona PHP la memoria?

Cada valor tiene un contador de referencias; cuando baja a cero, la memoria se libera inmediatamente. Los objetos que se referencian entre sí en un ciclo nunca llegan a cero, así que un recolector de ciclos se ejecuta cada vez que se llena su búfer de posibles raíces de ciclos (10.000 entradas por defecto) y los libera (gc_collect_cycles() lo ejecuta bajo demanda). Los arrays y las cadenas son copy-on-write: asignar $b = $a comparte los datos hasta que uno de los dos se modifica. Como cada petición empieza y termina limpia, las fugas de memoria importan sobre todo en workers de larga duración y consumidores de colas.

¿Cómo están implementados los arrays de PHP?

Un array de PHP es un mapa hash ordenado: conserva el orden de inserción y asigna claves int o string a valores, y por eso el mismo tipo sirve como lista, diccionario y pila. Las búsquedas por clave (isset($arr[$key])) tardan un tiempo constante de media, mientras que in_array() recorre todos los valores. Las claves de texto que parecen enteros se convierten: $a['1'] y $a[1] son el mismo elemento.

Ejercicios de programación habituales en entrevistas

Ejercicios cortos que se piden a menudo en directo. Cada función es una respuesta habitual; ejecútalas, añade tus propias entradas (incluida una vacía) y prepárate para explicar la complejidad temporal, que suele ser lo que comprueba el entrevistador.

Preguntas frecuentes

¿Cómo me preparo para una entrevista de desarrollador PHP?

Asegúrate de poder explicar y escribir código de lo básico sin consultarlo: comparación y tipos, arrays y sus funciones, POO (interfaces, clases abstractas, traits, static), excepciones y seguridad (sentencias preparadas, htmlspecialchars, password_hash). Después conoce un framework (Laravel o Symfony) y Composer lo bastante bien como para explicar un proyecto que hayas construido.

¿Qué versión de PHP debo conocer para una entrevista?

PHP 8. Los entrevistadores esperan que conozcas las funciones añadidas de la 8.0 a la 8.3: argumentos con nombre, match, el operador nullsafe ?->, tipos unión, promoción de propiedades en el constructor, enums, propiedades readonly y la sintaxis de callable de primera clase. Menciona el comportamiento de PHP 7 solo donde cambió, como 0 == "a".

¿Qué preguntas de PHP se hacen a los perfiles junior?

Sobre todo lo básico del lenguaje: == frente a ===, echo frente a print, comillas simples frente a dobles, isset frente a empty, include frente a require, GET frente a POST, sesiones frente a cookies y tareas sencillas con arrays como invertir, filtrar o contar valores. Espera al menos un ejercicio corto de programación.

¿Qué preguntas de PHP se hacen a los desarrolladores con experiencia?

Diseño y comportamiento interno: interfaces frente a clases abstractas, traits, late static binding, referencias, generadores y memoria, excepciones y manejo de errores, inyección SQL y transacciones, caché, autoloading con Composer y cómo estructurarías o probarías una funcionalidad. Se espera que las respuestas vengan con ventajas e inconvenientes, no con definiciones.

Ilustración de los lenguajes de programación de Coddy

Aprende a programar con Coddy

COMENZAR