Entrevista de trabajo PHP: Preguntas y respuestas frecuentes
Tiempo de lectura: 22.28 minutos
Si postulas a un trabajo como desarrollador PHP, es usual que te encuentres con preguntas técnicas en las entrevistas.
Ten en cuenta que las entrevistas pueden ser de distintos tipos. A veces son principalmente conversaciones sobre experiencias y proyectos desarrollados.
En otros casos se asignan tareas para su posterior revisión, o se proponen ejercicios para escribir código en vivo.
Pero una entrevista técnica muchas veces consta principal o únicamente de una serie de preguntas.
Este artículo nos prepara para tales casos.
¿Qué tan importante es memorizar las respuestas?
Desde mi punto de vista es mejor evaluar la lógica de programación, la habilidad para investigar, y cómo usamos ello para resolver problemas.
Sin embargo no está de más que revisemos preguntas de este tipo, para demostrar nuestro interés sobre un rol en particular dentro de un proyecto. En este caso como desarrolladores de software PHP.
Menciono esto porque:
Muchas veces usamos distintos lenguajes y tendemos a olvidar detalles específicos de cada uno si estamos cambiando constantemente entre ellos sin especializarnos.
Pero, como las empresas consideran importante hacer este tipo de preguntas, para tener mayor certeza de contratar a alguien con experiencia en un lenguaje particular, entonces revisemos sobre estos temas para tenerlos presentes.
Dicho esto, a continuación te presento un listado de las preguntas más comunes y sus correspondientes respuestas.
Preguntas y respuestas comunes en entrevistas para desarrollador PHP
Estas preguntas y respuestas las he recopilado de diferentes páginas (puedes consultar el listado al final del artículo).
Si conoces alguna más, que te resulte interesante, lo puedes comentar, y así podemos ir organizando un muy buen resumen entre todos.
Hay algunas preguntas básicas que he decidido omitir, ya que si estás postulando a un trabajo, lo más probable es que ya domines los fundamentos muy bien. Por ejemplo:
- ¿Cuál es la diferencia entre HTML, CSS, Javascript y PHP?
- ¿Cuál es la diferencia entre cliente y servidor?
Las preguntas siguientes son más bien específicas al lenguaje PHP, con respuestas que probablemente conocías pero que terminaste olvidando 🙂
Preguntas adaptadas de Guru99
¿Qué significan las siglas PHP?
Las siglas PHP significan "PHP: Hypertext Preprocessor".
¿Cómo es posible que el significado incluya nuevamente el término PHP?
Bueno, en la página del lenguaje a esto se le considera como un "acrónimo recursivo".
¿Qué versiones actuales de PHP existen?
Las versiones más recientes de PHP son 7.4 y 8.1.
Cada versión tiene un tiempo de soporte asignado.
¿Es posible ejecutar un script PHP desde la línea de comandos? ¿Cómo?
Sí. Para ello debemos simplemente escribir "php", seguido del nombre de archivo del script que queremos ejecutar:
php script.php
Nota: Para ejecutar PHP de manera interactiva en la consola podemos usar php -a
.
¿Cuál es la principal diferencia entre PHP 4 y 5?
PHP 5 incluye muchas más características sobre programación orientada a objetos.
¿PHP soporta herencia múltiple (multiple inheritance)?
PHP sólo soporta "single inheritance" (herencia simple).
Esto significa que cada clase sólo puede extender a partir de una única clase.
Nota: Una clase sí puede implementar múltiples interfaces, y en PHP también tenemos el concepto de Traits.
¿Qué representa una clase y un método cuando son declarados como final
?
La palabra reservada final
se introduce en PHP 5.
Una final class
es una clase que no puede ser extendida.
Una clase que incluye un método declarado como final
puede tener clases hijas, pero los métodos declarados como final
no pueden ser sobrescritos.
Nota: Hablamos de métodos porque son funciones al interior de una clase. Sin embargo, en la sintaxis de PHP, la declaración empezaría como final public function
para un método público.
¿Cómo funciona la comparación de objetos en PHP?
El operador ==
considera como iguales a 2 objetos si
- tienen los mismos atributos y valores (comparando cada uno con
==
), - y son además instancias de una misma clase.
Para verificar si 2 objetos hacen referencia a una misma instancia de una misma clase, usamos el operador ===
.
¿Cómo pueden interactuar PHP y Javascript?
PHP es un lenguaje de lado del servidor. Javascript es un lenguaje de lado del cliente.
Y pueden comunicarse de muchas maneras, que además aplican para cualquier otra tecnología backend:
-
PHP como tecnología backend genera respuestas ante las solicitudes de los usuarios. Entonces PHP puede devolver una vista HTML incluyendo código Javascript, e imprimir de esta manera la declaración de variables JS con valores asignados.
-
Enviar valores de JS a PHP es posible haciendo peticiones al servidor. Por ejemplo,
- haciendo uso de un formulario (con campos ocultos que contienen información asignada con JS),
- enviando parámetros GET al visitar una URL (sí, JS también puede generar redirecciones en el navegador),
- o haciendo peticiones asíncronas (Ajax).
De hecho, el servidor tiene la oportunidad de devolver una respuesta, y por tanto, comunicar valores nuevamente.
¿Cómo se gestionan los fallos producidos al ejecutar las funciones include()
y require()
?
Si la función require()
no puede acceder al archivo solicitado, entonces finaliza con un "fatal error".
En cambio la función include()
produce un "warning" y el script PHP continúa su ejecución.
¿Cuál es la principal diferencia entre require()
y require_once()
?
require()
y require_once()
cumplen con la misma tarea, pero la 2da función verifica si el script PHP ya se ha incluido, para evitar ejecutarlo nuevamente.
Nota: La misma idea aplica para include()
e include_once()
.
¿Qué función de PHP permite mostrar la información de una variable en un formato legible para humanos?
Para imprimir tal resultado usamos print_r()
.
¿Cómo se puede asignar un tiempo de ejecución infinito para un script PHP?
No es una práctica recomendada, ya que lo mejor es tener un límite y controlar la ejecución de nuestros scripts. Por ejemplo, para tareas que puedan exceder el tiempo límite se pueden usar queue jobs.
De todas formas, se logra agregando set_time_limit(0)
al inicio de un script.
Esto evitaría el error de maximum execution time exceeded
.
Y esta configuración también se puede definir en el archivo php.ini
.
¿Qué significa el mensaje de error Parse error in PHP - unexpected T_variable at line x
?
Este mensaje de PHP indica que se ha cometido un error de sintaxis, lo que ha causado que el programa no se pueda parsear adecuadamente y por tanto se detenga su ejecución.
Si el error no se encuentra en la línea x, el problema puede encontrarse en la línea anterior. Por ejemplo, debido a:
- la falta de un
;
, - llaves, comillas o corchetes sin sus pares de cierre,
- o en general, cualquier caracter no esperado.
¿Cómo es posible exportar data en un archivo de Excel?
Existen muchas bibliotecas para lograr ello.
La forma más común y sencilla es escribir sobre un archivo .csv
, que es un formato simple soportado por Excel.
Para ello, la idea es usar un delimitador (usualmente ,
o ;
) para separar los valores al momento de generar el archivo.
¿Para qué es útil la función file_get_contents()
?
Nos permite leer el contenido de un archivo. Y es posible almacenar el resultado en una variable string.
¿Cómo podemos verificar si el valor de una variable es un número, o si se trata de un valor alfanumérico?
- Es posible usar la función
is_numeric()
para verificar si una variable contiene un valor numérico o no. - Y es posible usar la función
ctype_alnum
para verificar si una variable contiene un valor alfanumérico o no.
¿Para qué es útil la función strip_tags()
de PHP?
Nos permite limpiar una cadena y eliminar las etiquetas HTML en su interior.
¿Para qué es útil una variable declarada como static
en una función?
Una variable static
se define dentro de una función sólo la primera vez que ésta es invocada.
Su valor puede ser modificado durante los siguientes llamados de dicha función, como se muestra a continuación:
function testFunction() {
static $testVariable = 1;
echo $testVariable;
$testVariable++;
}
testFunction(); // 1
testFunction(); // 2
testFunction(); // 3
¿Cómo se puede pasar una variable por referencia?
A fin de pasar una variable by reference
usamos un ampersand delante, de esta manera: $var1 = &$var2
.
¿Es posible comparar un integer 12 con un string "13" en PHP?
"13" y 12 sí se pueden comparar, ya que cuando un número se compara a una cadena, PHP realiza un cast hacia integer sobre la cadena.
¿Cómo es posible hacer un cast de tipos en PHP?
El nombre del tipo deseado se debe especificar dentro de paréntesis, antes de la variable que va a ser convertida:
- (int), (integer) - cast to integer
- (bool), (boolean) - cast to boolean
- (float), (double), (real) - cast to float
- (string) - cast to string
- (array) - cast to array
- (object) - cast to object
¿Cuándo una sentencia condicional debe terminar con endif
?
Cuando la condición se ha iniciado usando if:
y por tanto el bloque de código se está usando sin llaves.
¿Cómo se usa el operador condicional ternario en PHP?
Está compuesto de 3 elementos: una condición y 2 operandos que describen el valor resultante que puede tener la expresión, dependiendo de si se evalúa como verdadera o falsa:
$expr_condicional ? $resultado_si_true : $resultado_si_false
¿Para qué se usa la función func_num_args()
?
Indica el número de argumentos que se han enviado a una función (aquella desde la que se está usando).
Si la variable $var1
se inicia con el valor 10 y $var2
recibe como valor 'var1'
, ¿cuál es el valor de $$var2
?
$$var2
devuelve 10 como se muestra a continuación:
¿Qué significa acceder a una clase usando ::
?
Se usa ::
para acceder a métodos estáticos (static
methods) que no requieren inicializar objetos.
En PHP, ¿los objetos son pasados por valor o por referencia?
En PHP los objetos son pasados by value
, a menos que explícitamente se decida pasar by reference
.
¿Los constructores padres son llamados implícitamente dentro del constructor de una clase hija?
No. Un parent constructor
tiene que llamarse explícitamente si así se desea. Por ejemplo: parent::constructor($value)
.
¿Cuál es más rápido para concatenar cadenas?
$var1 = 'Hello ';
$var2 = 'World';
-
¿Combinar las 2 variables de esta manera
$var3 = $var1.$var2;
? -
¿O usando
$var3 = "$var1$var2";
?
La variable $var3
va a contener "Hello World".
Y el primer código es más rápido que el segundo, especialmente para grandes conjuntos de datos.
¿Que es una session
?
Una sesión es un mecanismo que nos permite guardar datos temporalmente, y así pueden estar disponibles a través de las distintas páginas que gestionamos con PHP.
A diferencia de una cookie, la información no se guarda en la computadora del usuario, sino en el servidor.
Es importante ya que el protocolo HTTP por sí mismo es stateless (no mantiene un estado).
¿Cómo se puede propagar una session id
?
Usualmente se gestiona a través de cookies
, pero ciertamente PHP también permite propagar una sid
a través de un parámetro en la URL.
¿Qué representan $GLOBALS
, $_SERVER
, $_FILES
, $_ENV
y $_COOKIE
?
Todos ellos son arreglos asociativos que contienen información:
-
$GLOBALS
incluye referencias hacia todas las variables definidas actualmente en el ámbito global. -
$_SERVER
contiene información sobre el servidor web (como paths, headers, y dónde se ubican los scripts). -
$_FILES
está compuesto por elementos subidos al actual script de PHP a través de una petición POST. -
$_ENV
consta de variables de entorno importadas al actual script de PHP. -
$_COOKIE
contiene los valores de las cookies enviadas por el navegador al actual script de PHP.
¿Es posible cambiar el tamaño máximo que pueden tener los archivos al ser subidos?
Sí, podemos cambiar el maximum size de los archivos subidos al servidor, cambiando el valor de upload_max_filesize
en el archivo de configuración php.ini
.
¿Qué es el scope de las variables?
El scope o ámbito de una variable es el contexto dentro del cuál una variable está disponible, y depende de cómo se define cada variable.
El ámbito se extiende sobre los archivos que son importados (ya sea usando include
o require
). Por ejemplo:
<?php
$a = 1;
include 'b.php';
Aquí la variable $a
estará disponible para el script b.php
.
Sin embargo, si definimos una función, se introduce un nuevo ámbito, llamado local function scope
.
Toda variable usada al interior de una función, por defecto, está limitada al ámbito local de la función. Por ejemplo:
<?php
$a = 1; /* global scope */
function test()
{
echo $a; /* reference to local scope variable */
}
test();
Este script no produce ninguna salida, dado que la sentencia echo
hace referencia a la versión local de la variable $a
, y no tiene ningún valor asignado en este ámbito.
En otros lenguajes, como en el lenguaje de programación C, las variables declaradas en un ámbito global están disponibles automáticamente para las funciones, a menos que específicamente se sobrescriban por una definición en el ámbito local. Esto puede causar inconvenientes en caso que se cambie el valor de una variable global inconscientemente.
En PHP las variables globales deben ser declaradas como tal, dentro de una función, para habilitar su uso.
Esto se consigue usando la palabra reservada global
. O bien se puede acceder a ellas a través del arreglo asociativo $GLOBALS
.
¿Cuál es la diferencia entre el operador BITWISE AND
y el operador LOGICAL AND
?
Tanto $a and $b
como $a && $b
se corresponden con el operador lógico AND, y el resultado es verdadero si tanto $a
como $b
son verdaderos.
Por otro lado, el operador bitwise AND se expresa como $a & $b
, y realiza una evaluación a nivel de bits.
Por ejemplo, 8 & 5
da como resultado 0, ya que a nivel de bits se está comparando 1000 con 0101 y el resultado es 0000 (en ninguna posición coincide dos veces el bit 1).
¿Qué es una persistent cookie
?
Por defecto, las cookies existen temporalmente y se pierden al cerrar el navegador.
Una "persistent cookie" se almacena en el navegador y persiste en el tiempo, según la fecha de expiración que se le haya asignado.
También se le conoce como stored
o permanent
cookie, y generalmente se usa para guardar preferencias de los usuarios.
De modo que en su próxima visita se le pueda brindar una mejor experiencia.
¿Cómo actúa el operador ===
cuando es usado con arreglos?
$a === $b
es TRUE si $a y $b tienen los mismos pares clave-valor, en el mismo orden y con los mismos tipos.
¿Cuál es la diferencia entre $a != $b
y $a !== $b
?
-
!=
representa "inequality" (verdadero si no son iguales), - y
!==
representa "non-identity" (verdadero si no son idénticos).
La diferencia es que la segunda comparación es estricta.
En la 1ra comparación si los tipos no coinciden se realiza una conversión de tipos.
En el 2do caso, se compara tanto el valor como el tipo (sin hacer cast).
¿Cómo podemos determinar si una variable PHP es un objeto creado a partir de una clase determinada?
Para verificar ello usamos instanceof
.
¿Cómo podemos determinar si una variable tiene un valor asignado?
La función isset
devuelve un boolean
indicando si una variable tiene un valor asignado y es not NULL.
¿Cuál es la diferencia entre las funciones strstr()
y stristr()
?
La función strstr(allStr, occ)
devuelve una parte de la cadena allStr
desde la primera ocurrencia de la cadena occ
hasta el final de allStr
.
Esta función es case sensitive
(sensible a mayúsculas y minúsculas).
La función stristr()
es idéntica, pero es case insensitive
.
¿Cuál es la diferencia entre for y foreach?
Un for
se expresa de esta manera:
for (expr1; expr2; expr3)
statements
- La primera expresión
expr1
se ejecuta una vez al inicio. - En cada iteración, la expresión
expr2
es evaluada, y determina si el bucle continúa. Es decir, si se evalúa como TRUE, los statements dentro del for se ejecutan. - La expresión
expr3
se ejecuta al final de cada iteración.
Un foreach
en cambio es más específico, ya que nos provee una forma sencilla para iterar sobre arrays y objects.
¿Cuáles son los 3 tipos de errores que pueden ocurrir en PHP?
Las 3 clases básicas de errores son: notices (non-critical), warnings (serious errors) y fatal errors (critical errors).
¿De qué manera es posible pasar una variable entre distintas páginas mientras se navega?
Es posible usando sessions, cookies, campos de formulario ocultos, parámetros GET en las URLs visitadas.
¿Es posible destruir una cookie
?
Sí, es posible, asignando a la cookie un "expiration time" correspondiente a una fecha y hora pasadas.
¿Cuál es el default session time en PHP?
El tiempo por defecto para las sesiones en php es hasta cerrar el navegador.
¿Cuál es la diferencia entre 034
y 0x34
?
La expresión 034
es el valor octal de 34, y 0x34
es el valor hexadecimal de 34.
Es decir, 28 y 52, que resultan de 3 * 8 + 4
y 3 * 16 + 4
respectivamente.
¿Es posible compartir una misma instancia de Memcache entre múltiples proyectos PHP?
Memcache es un sistema distribuido, de almacenamiento en memoria caché, y sí es posible compartir una instancia de Memcache entre varios proyectos.
Podemos tener más de una instancia Memcache en el mismo host, siendo cada una totalmente independiente. Sólo será necesario indicar de qué instancia se quiere obtener data, o sobre qué instancia guardar valores, al realizar operaciones.
¿Cómo podemos actualizar datos en caché cuando hacemos cambios?
Podemos seguir diferentes estrategias:
- Limpiar la memoria Caché de manera proactiva: Limpiar cada vez que se hacen cambios en los datos (por ejemplo luego un insert o update).
- Restablecer la memoria Caché: La idea es similar, pero en vez de eliminar valores y esperar por la siguiente solicitud, éstos se calculan de nuevo inmediatamente.
Preguntas adaptadas de Toptal
¿Cómo se puede corregir el siguiente código?
Si ejecutamos:
$str1 = 'wubba lubba dub dub';
$str2 = 'wubba';
if (strpos($str1, $str2)) {
echo $str1 . " contiene " . $str2;
} else {
echo $str1 . " no contiene " . $str2;
}
Nos devuelve:
wubba lubba dub dub no contiene wubba
¿Cómo lo podemos corregir?
Lo que ocurre es que:
strpos()
devuelve la posición de donde inicia $str2
en $str1
sólo si se encuentra,
de caso contrario devuelve false
.
En este ejemplo, strpos()
devuelve 0. El if convierte este entero como false
y por tanto se ejecuta lo que tenemos dentro del else
.
Lo correcto es usar una comparación estricta con relación al valor devuelto por strpos()
. De esta manera:
if (strpos($str1,$str2) === false) {
echo $str1 . " no contiene " . $str2;
} else {
echo $str1 . " contiene " . $str2;
}
Nota: Si usamos ==
en vez de ===
nuevamente nos encontraríamos con el problema antes mencionado. Esto es porque ==
realiza una conversión de tipos, y considera al 0
como false
.
¿Cuál es el resultado del siguiente código?
$x = 5;
echo $x+++$x++;
echo "<br>";
echo $x;
echo "<br>";
echo $x---$x--;
echo "<br>";
echo $x;
El resultado sería:
11
7
1
5
Para explicar esto necesitamos entender 2 cosas:
-
La expresión
$x++
dice que usemos el valor actual de$x
y luego incrementemos su valor en 1. De manera similar,$x--
nos dice que usemos el valor actual de$x
y luego disminuyamos su valor en 1. -
El operador de incremento (
++
) tiene mayor precedencia que el operador suma (+
) en el orden en que se realizan las operaciones.
Teniendo esto en cuenta, entendemos que $x+++$x++
se evalúa de la siguiente manera:
La primera vez que se accede a $x
su valor es 5 (antes de incrementar) y la 2da vez que se accede a $x
su valor es 6 (justo antes de que incremente una vez más),
por tanto la expresión evalúa 5 + 6, lo que resulta en 11
.
Luego de esta operación, el valor de $x
es 7
dado que ha incrementado su valor 2 veces.
De manera similar, $x---$x--
se evalúa de la siguiente manera:
La primera referencia a $x
es cuando su valor todavía es 7, y la 2da referencia a $x
es cuando su valor es 6.
Así la operación es 7 - 6, y resulta en 1
.
Luego de esto, el valor de $x
vuelve a su valor original, que es 5
, debido a que ha incrementado su valor 2 veces, pero también decrementado 2 veces.
¿Cuáles serán los valores de $a
y $b
después de ejecutar el siguiente código?
$a = '1';
$b = &$a;
$b = "2$b";
Tanto $a
como $b
serán iguales al string "21".
Esta es la explicación:
La sentencia $b = &$a;
asigna a $b
como valor una referencia hacia $a
(en vez de asignar el valor de $a
se asigna una referencia hacia $a
, por el uso del ampersand).
Mientras $b
siga siendo una referencia hacia $a
, todo lo que le ocurra a $a
afectará a $b
, y viceversa.
Por tanto, al ejecutar $b = "2$b"
, $b
recibe el valor del string "2" seguido del valor de $b
(que es el mismo que $a
) que es 1.
Así el resultado asignado a $b
es el string "21" (la concatenación de "2" y "1").
Y, dado que $b
es una referencia a $a
, esto tiene el mismo efecto sobre $a
, y así ambos terminan con el valor de "21".
¿Cuál es el resultado de imprimir cada una de las siguientes comparaciones y por qué?
var_dump(0123 == 123);
var_dump('0123' == 123);
var_dump('0123' === 123);
var_dump(0123 == 123)
imprime bool(false)
ya que el 0 que está adelante en 0123 le dice al intérprete de PHP que se trata de un octal (en vez de decimal).
El octal 123 equivale al valor 83 decimal, y la comparación se resuelve como falsa.
var_dump('0123' == 123)
imprime bool(true)
dado que el string 0123 será convertido a integer al evaluarse la comparación con un valor integer.
Al realizar la conversión (de cadena a entero), el 0 del inicio es ignorado y el valor se trata como un decimal. Así ambos valores son 123 y por tanto son iguales.
var_dump('0123' === 123)
imprime bool(false)
dado que realiza una comparación más estricta, que no aplica ninguna conversión de tipos.
¿Qué problema presenta el código siguiente? ¿Qué salida produce? ¿Y cómo se puede corregir?
$referenceTable = array();
$referenceTable['val1'] = array(1, 2);
$referenceTable['val2'] = 3;
$referenceTable['val3'] = array(4, 5);
$testArray = array();
$testArray = array_merge($testArray, $referenceTable['val1']);
var_dump($testArray);
$testArray = array_merge($testArray, $referenceTable['val2']);
var_dump($testArray);
$testArray = array_merge($testArray, $referenceTable['val3']);
var_dump($testArray);
La salida que produce es:
array(2) { [0]=> int(1) [1]=> int(2) }
NULL
NULL
También podríamos ver 2 warnings, similares a los siguientes:
Warning: array_merge(): Argument #2 is not an array
Warning: array_merge(): Argument #1 is not an array
El problema aquí es que, si uno de los argumentos de array_merge()
no es un array, el valor devuelto por esta función será NULL
.
Entonces, aunque uno podría pensar que array_merge($unArrayValido, NULL)
devuelve $unArrayValido
, ¡en realidad la función devuelve NULL
!
Y esto no se encuentra bien explicado en la documentación de PHP.
Como resultado, la llamada a $testArray = array_merge($testArray, $referenceTable['val2'])
se evalúa como $testArray = array_merge($testArray, 3)
y, dado que 3 no es un array, la función devuelve NULL
, lo que termina asignando a $testArray
el valor NULL
.
Entonces, cuando invocamos por tercera vez a array_merge()
, $testArray
es NULL
y array_merge()
devuelve NULL
nuevamente.
Esto expica por qué el primer warning se queja acerca del argumento #2, y el segundo warning con relación al argumento #1.
La solución para esto es sencilla:
Si nosotros hacemos cast del segundo argumento a array, podemos obtener los resultados esperados.
Por ejemplo, podríamos hacerlo de esta manera:
$testArray = array_merge($testArray, (array)$referenceTable['val1']);
var_dump($testArray);
$testArray = array_merge($testArray, (array)$referenceTable['val2']);
var_dump($testArray);
$testArray = array_merge($testArray, (array)$referenceTable['val3']);
var_dump($testArray);
Y el resultado sería el siguiente (sin producir warnings):
array(2) { [0]=> int(1) [1]=> int(2) }
array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
array(5) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) }
¿Qué salida produce el siguiente código y por qué?
$x = true and false;
var_dump($x);
Para sorpresa de muchos, el código imprime bool(true)
. Muchos dirán, ¡se trata de un operador and
no de un or
!
El tema es que el operador =
tiene precedencia sobre el operador and
en el orden de las operaciones.
Así la sentencia $x = true and false
resulta siendo equivalente a lo siguiente:
$x = true; // se asigna a $x el valor true
true and false; // esto resulta en false, pero no tiene efecto alguno
Este es un buen ejemplo de por qué los paréntesis son muy útiles para aclarar cuál es la verdadera intención de una operación. Su uso es una buena práctica, en cualquier lenguaje.
En este caso, si la sentencia se hubiese escrito como $x = (true and false)
, entonces $x
habría recibido el valor false
como normalmente se espera.
Nota: Curiosamente esto no ocurre con $x = true && false;
.
¿Cuál es el resultado de la expresión 3 + "15%" + "$25"
?
La respuesta es 18. Y esta es la explicación:
PHP realiza una conversión de tipos automáticamente, dependiendo del contexto en que una variable o valor es usado.
Cuando una operación aritmética involucra un string, esta cadena será interpretada como el tipo de dato numérico más apropiado para la expresión que se está evaluando.
Así, si el string empieza con uno o varios caracteres numéricos, el resto de la cadena (de existir) será ignorado y el valor resultante es interpretado como el tipo numérico más apropiado.
Por otro lado, si el string empieza con un caracter no numérico, entonces se evaluará como 0.
Con ello en mente, podemos ver cómo "15%" se evalúa como un valor numérico 15, y "$25" se evalúa como 0, lo que explica que el resultado de 3 + "15%" + "$25"
sea 3 + 15 + 0
, es decir, 18.
Desde PHP 7.2, este código produce mensajes de error:
- Notice: A non well formed numeric value encountered
- Warning: A non-numeric value encountered
Esto es con relación a los valores "15%" y "$25" respectivamente.
¿Cuál será el valor de $text
y qué devolverá strlen($text)
luego de ejecutar el código siguiente?
$text = 'Juan ';
$text[10] = 'Ramos';
El valor de $text
será el string "Juan R" (es decir, 'Juan', seguido de 6 espacios, seguido de una 'R'). Y strlen($text)
devolverá 11.
Hay 2 cosas a tener en cuenta aquí.
Primero que todo, dado que $text
es un string, asignar un valor a una posición de $text
simplemente asigna un caracter, y no la cadena entera.
Es decir, la sentencia $text[10] = 'Ramos'
sólo asigna el caracter 'R'
, que es el primer caracter en la cadena 'Ramos', dado que cada elemento de un string es sólo un caracter.
Y en segundo lugar, la asignación del valor 'R'
a $text[10]
, que sería el elemento décimo primero (ya que los índices son zero-based
) ocurre sin inconvenientes, incluso cuando la longitud de la cadena era sólo 5 antes de la asignación (ya que el string se inicializó como 'Juan '
).
Mientras que los compiladores o intérpretes en otros lenguajes se pueden quejar (diciendo algo como out of bounds index error
), cuando asignamos un caracter al índice 10 de una cadena de sólo 5 caracteres, PHP es bastante "accommodating" y permite hacer esto, dejando a los caracteres intermedios como espacios en blanco.
Si var_dump(PHP_INT_MAX)
devuelve int(9223372036854775807)
, ¿cuál será el resultado de var_dump(PHP_INT_MAX + 1)
? Y así mismo, ¿cuál será el resultado de var_dump((int)(PHP_INT_MAX + 1))
?
PHP_INT_MAX
es una constante PHP que se corresponde con el mayor valor entero admitido. Este valor depende de la versión de PHP que se está usando y la platforma sobre la que se está ejecutando.
Ante esta pregunta no es importante indicar un valor exacto como respuesta, sino más bien explicar qué sucederá y por qué.
El resultado de var_dump(PHP_INT_MAX + 1)
se mostrará como un double
. Para este caso específico se mostrará double(9.2233720368548E+18)
.
Lo importante es explicar que PHP gestiona los grandes números enteros convirtiéndolos a double
s (que pueden almacenar valores más grandes).
Y curiosamente, el resultado de convertir la suma a entero con var_dump((int)(PHP_INT_MAX + 1))
mostrará un número negativo. Para este caso específico muestra int(-9223372036854775808)
.
Nuevamente, lo importante aquí es saber que el valor será mostrado como un número negativo, en vez de responder con un valor exacto.
¿Cuáles son las diferencias entre echo
y print
en PHP?
echo
y print
son muy parecidos en PHP. Ambos son usados para imprimir valores en pantalla.
Las únicas diferencias son:
-
echo
no devuelve un valor, mientras queprint
devuelve el valor 1 (esto permite queprint
se use en expresiones). -
echo
admite múltiples parámetros (aunque dicho uso no es común), mientras queprint
sólo acepta un único argumento.
¿Qué usos tiene la función header()
en PHP?
header()
es usado para:
-
redirigir de una página a otra:
header("Location: index.php");
- enviar un HTTP status code:
header("HTTP/1.1 200 OK");
- responder con headers HTTP:
header('Content-Type: application/json');
¿Cómo puedes determinar si un número es par o impar sin usar condiciones ni bucles?
Podemos usar el operador módulo (%
), para obtener el residuo de dividir el número entre 2.
Si el residuo es 0, quiere decir que el número es par (even
), en cambio si el residuo es 1 será un impar (odd
).
$arr = ["even", "odd"];
$num = 13;
echo "It is " . $arr[$num % 2];
Así el residuo es usado como índice al buscar la respuesta en el arreglo $arr
.
¿Cuál es la principal diferencia entre sessions
y cookies
?
Las sessions
almacenan los valores en el servidor, y las cookies
almacenan valores en el navegador del usuario.
Preguntas adaptadas de Codementor
¿Cómo podemos obtener la dirección IP de un cliente?
Una solución es acceder al valor de $_SERVER['REMOTE_ADDR']
.
Si un usuario se conecta a través de un proxy, también se suele consultar $_SERVER['HTTP_X_FORWARDED_FOR']
.
Sin embargo este valor pudo haber sido alterado.
Los frameworks PHP generalmente ofrecen funciones para acceder a la IP del cliente, e internamente evalúan condiciones basadas en distintos valores, incluyendo los antes mencionados.
¿Para qué son útiles las funciones unlink()
y unset()
?
- La función
unlink()
elimina el archivo indicado de nuestro filesystem. - La función
unset()
asigna a una variable el valor deundefined
.
¿Qué diferencias encontramos entre GET y POST?
GET muestra la data enviada como parámetros en la URL. Para POST esta información no se muestra, ya que se encuentra como parte del cuerpo del request.
Las peticiones GET tienen un tamaño máximo, generalmente entre 2 y 8 KB. Las peticiones POST no presentan estas restricciones.
GET permite sólo ASCII data. POST no tiene dicha restricción, también admite binary data.
Normalmente GET se usa para obtener data, mientras que POST para realizar operaciones, como insert y update.
Las peticiones GET se pueden almacenar en caché, formar parte del historial de navegación, agregar a favoritos. Con POST no ocurre ello.
Entender los fundamentos del protocolo HTTP es importante para los desarrolladores web, y la diferencia entre los verbos GET y POST son una parte esencial de ello.
¿Cómo se puede habilitar el informe de errores en PHP?
Se debe verificar que "display_errors" sea igual a "on" en el archivo php.ini
, o declarar ini_set('display_errors', 1)
en el script correspondiente.
También se puede incluir error_reporting(E_ALL)
en el código, para mostrar todos los tipos de error durante la ejecución del script.
Habilitar los mensajes de error es importante, especialmente durante el proceso de depuración, ya que así uno puede obtener información más detallada sobre el error que se ha producido.
¿Qué son los Traits?
Un Trait puede definir métodos y propiedades que luego podemos incluir en una clase, haciendo uso de la palabra reservada use
en el cuerpo de la misma.
Los Traits nos permiten reusar y organizar nuestro código, y comprenden una característica importante en lenguajes como PHP, donde la herencia múltiple de clases no está disponible.
Un Trait sin embargo no es una clase, y por tanto no se pueden crear instancias a partir de ellos.
¿Qué representan los métodos __construct()
y __destruct()
en una clase PHP?
Estos son conceptos relacionados con la programación orientada a objetos en PHP.
Todos los objetos en PHP incorporan un método Constructor y Destructor. Estos métodos no devuelven valores.
El método Constructor de una clase es llamado inmediatamente al crear una nueva instancia de dicha clase, y es usado para inicializar las propiedades.
El método Destructor no recibe argumentos, y es llamado antes de desasignar memoria para un objeto, o al finalizar la ejecución de un script PHP.
Si tenemos un string $str = '1,2,3,4,5,6,7';
, ¿cómo podemos obtener la suma de los enteros que contiene?
array_sum(explode(',', $str))
La función explode
es una de las más usadas en PHP, y nos permite obtener los elementos en un arreglo (aquellos que están separados por una coma en la cadena).
Luego podemos usar array_sum
para sumar todos los elementos contenidos en el arreglo.
Nota: Se puede lograr lo mismo usando bucles y variables auxiliares, pero es conveniente demostrar que se conocen estos métodos.
¿Cuáles son los 3 niveles de accesibilidad disponibles en PHP y cómo los definirías?
- Private.- Visible sólo para la misma clase.
- Public.- Visible para cualquier código que haga uso de la clase.
- Protected.– Visible para la clase misma, para clases padre, y clases que extienden a partir de la clase actual.
La declaración de métodos y atributos privados o protegidos es importante, a fin de expresar mejor la responsabilidad que tienen las clases.
Esta pregunta, sobre los privilegios de acceso o visibilidad, busca evaluar qué tanto conoce un desarrollador más allá de la capacidad de "escribir código que funcione".
¿Cómo se puede prevenir la advertencia Warning: Cannot modify header information – headers already sent
?
No se debe imprimir nada sobre el navegador antes de usar código que asigne HTTP headers.
Por ejemplo, si un desarrollador hace echo
de algún valor, entonces ya no podrá enviar cookies o headers.
Esto también aplica para los mensajes de error generados:
Si ocurre un error antes de asignar un header, y la directiva display_errors
está activa, también aparecera dicha advertencia.
¿Qué son las inyecciones SQL y cómo prevenirlas?
Las inyecciones SQL buscan alterar consultas SQL que van a ser o están siendo ejecutadas.
Una consulta SQL modificada podría, por ejemplo, filtrar información sensible de una base de datos, como datos personales que deberían permanecer privados, o credenciales de acceso a un sistema.
Para prevenir esta vulnerabilidad siempre se debe revisar y corregir todo valor de entrada que ingresan los usuarios.
En PHP nativo (sin frameworks), los desarrolladores sin experiencia suelen pasar esto por alto, debido al fácil acceso que se tiene a $_GET
y $_POST
sin un control adecuado.
No sólo ello. También hay otras maneras en que un atacante puede manipular variables que son usadas posteriormente en consultas SQL, por ejemplo a través de cookies o incluso la subida de archivos (filenames).
Por esto es importante usar prepared statements
de manera consistente en toda nuestra aplicación.
Las funciones que empiezan con mysql_
se han declarado como obsoletas desde PHP 5.5 justamente por presentar este inconveniente.
Se recomienda el uso de PDO, que además está disponible para otros gestores de bases de datos, no solo MySQL.
Las funciones que empiezan con mysqli_
son una opción, pero estos días es realmente conveniente usar PDO, ODBC o DBA para obtener una mayor abstracción.
Idealmente se recomienda usar un ORM (object-relational mapping), como Doctrine o Propel, para no lidiar con la escritura de consultas SQL. Esto permite asociar filas de una base de datos con objetos de nuestra aplicación, donde cada tabla se asocia con un modelo determinado.
¿Por qué usarías ===
en vez de ==
?
Si queremos realizar una comparación respetando los tipos de los operandos, el operador ===
hará eso exactamente. Tal como sucedería con un lenguaje fuertemente tipado.
Por otro lado, ==
realizaría una conversión de tipos temporalmente, sobre los valores comparados, intentando los tipos de dato coincidan antes de hacer la comparación.
El operador de identidad (===
) presenta un mejor resultado por no tener que lidiar con conversión de tipos.
Esto es importante especialmente al comparar variables y valores true/false. Usar ==
en estos casos podría generar confusión al tener en consideración también al 0/1 u otra representación similar.
¿Qué son los PSRs? Escoge 1 y descríbelo brevemente.
Las siglas PSRs significan PHP Standards Recommendations. Como su nombre lo indica, son recomendaciones que buscan estandarizar aspectos comunes del desarrollo con PHP.
Un PSR es por ejemplo PSR-2, que es una guía sobre coding style. Aquí puedes ver más información sobre PSR-2.
¿Por qué seguirías un PSR?
La forma de escribir y organizar código varía entre desarrolladores y empresas.
Esto puede causar inconvenientes al revisar y colaborar con el código de otros desarrolladores, por la ausencia de uniformidad.
Un PSR es un estándar que determina cómo debería verse el código, reduciendo así las discrepancias y mejorando la legibilidad en general.
¿Usas Composer? ¿Qué beneficios te aporta?
Composer es una herramienta para la gestión de dependencias. Es decir, instalación de bibliotecas y actualización a nuevas versiones.
El beneficio es que proporciona una forma consistente para gestionar las bibliotecas que han sido cargadas como dependencias al proyecto, y así invertir menos tiempo en ello.
Preguntas adicionales
Las siguientes preguntas son más abiertas y generales. Puedes investigar y organizar tus respuestas según creas conveniente.
Sólo ten en cuenta de no responder con un simple sí/no, o con una oración muy corta.
Lo ideal es que puedas argumentar, sin llegar tampoco al extremo de extenderte mucho.
Procura tener respuestas que duren menos de 60 segundos para no aburrir o cansar al entrevistador.
- ¿Qué opinas y qué experiencia tienes con relación a unit testing?
- ¿Qué experiencia tienes trabajando con bases de datos? ¿Cuáles has usado?
- ¿Qué opinas acerca de TDD?
- ¿Qué características nuevas incorpora PHP7 y qué opinas de estos cambios?
Referencia
Para este resumen se consultaron los siguientes enlaces: