Desarrollo

Valor null y funciones var_dump y print_r

Desarrollo PHP

Después de haber visto con una cierta profundidad todo el tema sobre los formularios, vamos a hacer un pequeño paréntesis para introducir un concepto nuevo, null, y aprender sobre dos funciones, var_dump y print_r, que nos pueden ayudar en la depuración de nuestros programas.

Ya hemos recorrido una buena parte en cuanto a los conceptos básicos sobre programación y a PHP en particular, entrando ya en algún terreno algo espinoso. Podéis ver, en el índice de contenidos, todo lo publicado hasta ahora junto a los proyectos futuros.

El valor especial null

En programación es habitual hacer muchas veces referencias al valor especial nulo, conocido y representado normalmente como null. Este valor representa, realmente, a una variable que no tiene valor. Dependiendo del lenguaje de programación puede ser un poco más detallado o menos, pero básicamente podemos considerar una variable como null cuando todavía no tiene un valor.

null no es 0

Aunque podamos pensarlo, e incluso en algún programa que creemos podamos considerar este caso equivalente, la realidad es que null no significa que sea 0. El valor expresado como 0 es propiamente un valor, tiene sus propiedades y nos indicado algo. Sin embargo, null no significa nada, no existe, no tiene razón de ser como tal y básicamente nos ayudará a conocer ésto, que no hay nada.

Por ejemplo, Juan ha cursado la asignatura de programación, pero su capacidad para comprenderla no fue buena, acabó por no preparársela bien y acudió al examen simplemente a ver qué tal era. Se encontró con que no comprendía absolutamente nada y sacó un 0 en el examen. Sin embargo, Pedro decidió no matricularse en esa asignatura, por lo que su nota es null, no existe. Para uno, el 0 tiene sentido, para el otro no.

Podemos asignar el valor null a nuestras variables y podemos tratar de forma diferente la ausencia de valor del valor 0. O, en algunas ocasiones, la ausencia de valor puede servirnos igual que si fuera un cero (una lista de la compra vacía o una lista de la compra con 0 elementos puede que la consideremos igual).

Aunque penséis que no tiene mucho sentido este valor, se utilizará más de lo que parece, e incluso en algunos lenguajes de programación es mucho más útil (por ejemplo, no será lo mismo un puntero a memoria con valor X que un puntero a memoria que apunte a null, es decir, a ningún sitio).

var_dump y print_r

Presentamos estas funciones, las cuales nos van a ayudar especialmente a depurar nuestro código, aunque alguien puede ser avispado y utilizarlas de alguna otra forma. Pero no conozco a nadie que las utilice que no sea para depurar. Estas funciones muestran la información que contiene una variable de formas distintas.

Vamos a ver algún ejemplo para ver qué hacen. Tenemos un array con ciertos valores y vamos a mostrar por pantalla lo que imprimen var_dump y print_r.

<?php

<?php

$array = array(
	'Primer elemento',
	5,
	'tercero' => 'Tercer elemento',
	array(
		'uno' => 'Ésto es un array dentro de otro',
		2,
		'Último elemento de este array interno'
	),
	8 => 6 * 5,
	'¿Qué índice hay aquí?'
);

echo '<pre>';

print_r($array);
var_dump($array);

echo '</pre>';

?>

Mostrando los datos por pantalla

Este artículo nos viene bien para recordar el tratamiento de los índices con los arrays, que ahora podremos ver bien en el momento en que mostremos por pantalla lo que muestran var_dump y print_r. Luego lo extenderemos

Etiqueta <pre>

Antes de nada, aclarar lo que hacen las etiquetas <pre> que hemos impreso en nuestro programita de ejemplo. Con estas etiquetas HTML vamos a mostrar lo que se contenga entre ellas con texto “preformateado”. En pocas palabras, en este caso nos permitirá mostrar los datos de una forma más ordenada y en varias líneas. Si no las hubiéramos utilizado, los datos hubieran salido en una línea y más difíciles de leer. Podéis hacer la prueba quitándolas, pues al final es pura estética.

Función print_r

Vamos a enfocarnos primero en la función print_r, la cual es la que menos información nos va a dar. Si ejecutamos el código de antes y vemos lo que nos muestra esta función, nos vamos a encontrar con lo siguiente:

Array
(
    [0] => Primer elemento
    [1] => 5
    [tercero] => Tercer elemento
    [2] => Array
        (
            [uno] => Ésto es un array dentro de otro
            [0] => 2
            [1] => Último elemento de este array interno
        )

    [8] => 30
    [9] => ¿Qué índice hay aquí?
)

Vemos que esta función nos imprime, en primer lugar, que la variable que le hemos indicado es un Array. Posteriormente, abre paréntesis para mostrarnos todos sus elementos en clave [índice] => valor, incluido el array que hemos introducido dentro de nuestro array inicial. Así pues, podemos ver de un vistazo toda la información guardada en el array.

Antes de pasar a observar bien los índices del array, veamos qué hace la otra función.

Función var_dump

Con esta función obtendremos el mismo comportamiento que la anterior pero, en esta ocasión, se nos brindarán más datos. Veamos lo que nos muestra por pantalla:

array(6) {
  [0]=>
  string(15) "Primer elemento"
  [1]=>
  int(5)
  ["tercero"]=>
  string(15) "Tercer elemento"
  [2]=>
  array(3) {
    ["uno"]=>
    string(32) "Ésto es un array dentro de otro"
    [0]=>
    int(2)
    [1]=>
    string(38) "Último elemento de este array interno"
  }
  [8]=>
  int(30)
  [9]=>
  string(25) "¿Qué índice hay aquí?"
}

Podemos ver ciertas diferencias con la anterior. En primer lugar, al igual que print_r, también vemos inicialmente que estamos imprimiendo un array pero, en esta ocasión, entre paréntesis se nos indica también el número de elementos totales que tiene el array. ¡Una información más que la anterior función no nos daba tan fácilmente!

Una vez listando los elementos, entre llaves esta vez, vemos una estructura parecida pero con un dato nuevo que no muestra print_r. Ahora vemos de qué tipo es cada elemento, pues después de indicar su índice, nos muestra si es un string, un int o un array, en este caso, pero haría lo mismo con los demás tipos de datos. Igualmente, nos muestra el tamaño de esos elementos. En el caso de un string nos muestra la longitud del texto guardado, en el caso del array ya hemos comentado que muestra el número total, pero en el caso del int vemos que, entre paréntesis, muestra el propio número guardado. Un int “no tiene tamaño” como tal (aparte de las restricciones de cuál es el número máximo que se puede guardar y que comentamos en su momento).

¿Cuál debemos usar?

No hay una respuesta a esta pregunta. Usad la que queráis dependiendo del tipo de información que necesitéis, si es más o menos detallada. En mi caso me he acostumbrado a usar más var_dump por mostrar más detalles, pero algunas veces me valdría con print_r.

Como he comentado, básicamente las utilizaremos para depurar y saber qué hay en cada momento. Podemos tener un error en un programa y no sabemos qué está pasando, por lo que imprimimos un var_dump en un momento de la ejecución para saber qué datos estamos tratando y vemos que tenemos, por ejemplo, un entero cuando esperábamos un string.

Recordando la indexación en los arrays

Independientemente de lo que realizan estas funciones, quizá hemos mirado con extrañeza lo que está pasando con los índices en los arrays. Vamos a recapitular uno por uno y ver por qué tienen esos índices.

El primer elemento del array, con valor “Primer elemento” tiene índice 0. Ésto es normal y esperable, pues no le hemos definido un índice, así que coge el primer índice numérico, el 0. Lo mismo pasa con el segundo elemento del array, con valor 5 y que recibe el siguiente índice, un 1.

A continuación definimos un índice para el siguiente elemento, cuyo índice será el string “tercero” y de valor le hemos puesto “Tercer elemento”. Como este elemento sí tiene índice definido, es el que se guarda.

Ahora viene quizá la primera rareza. El cuarto elemento es un array al que no le hemos definido índice. Vemos que se le ha asignado el índice 2. ¿Por qué? ¿No debería tener el índice 3 al ser el cuarto elemento? No, pues el siguiente índice numérico no gastado es el 2, pues ya hemos visto que al tercer elemento le hemos definido índice propio. Mucho cuidado entonces con ésto, porque el cuarto elemento, que debería tener índice 3, realmente tiene índice 2.

Fijáos que ocurre lo mismo dentro de este segundo array. Al primer elemento le hemos definido un índice llamado “uno”, pero a los dos siguientes no les hemos definido índices y han cogido los numéricos 0 y 1 pese a ser el segundo y tercer elementos.

Seguimos adelante y vemos que, al quinto elemento le hemos asignado un índice numérico esta vez, el 8, y su valor es una multiplicación entre el 6 y el 5. Imprimiendo los valores de la variable vemos que realmente se ha realizado la multiplicación, es decir, está guardado el número 30. Y, además, el índice numérico es el 8, como hemos colocado.

Y ya, llegando al final, guardamos el valor “¿Qué índice hay aquí?” sin índice definido. ¿Cuál hay? Pues el siguiente al último numérico que había, el cual no es el 2, sino el 8 que nosotros mismos hemos definido. Al definir un índice numérico, hemos redefinido por dónde iba ese índice y ahora, el nuevo elemento, tiene índice 9.

Gracias estas funciones var_dump y print_r hemos podido ver mucho mejor estos detalles que con la mera teoría.

Consejo

Evita utilizar índices numéricos y no numéricos en un mismo array.

Creo que, viendo este ejemplo, cae por su propio peso. Si empezamos a mezclar índices numéricos con no numéricos en un mismo array, corremos el peligro de acabar equivocándonos. Intentar evitarlo creo que es un buen consejo.

La importancia de depurar

Depurar nuestros programas es, además de importante, muchas veces necesario. Nadie (o casi nadie) programa todo a la primera, sin errores, teniendo en cuenta todos los casos y sin necesidad de comprobar que todo haya ido correctamente. Muchos recursos de las empresas se van en tiempo de depuración, pues según qué programas, un error puede ser fatal.

Hay que probar todas las opciones posibles, probar y comprobar todo lo que se pueda. Comprobar los casos extremos en nuestros arrays, el caso peor que pueda haber, el controlar que no nos salgamos del array… en fin, multitud de comprobaciones. Y para ello estas dos funciones nos pueden venir muy bien.

Pero, cuidado, los errores lógicos (aquellos que el programa no puede detectar porque sintácticamente todo está bien) son los más difíciles de comprobar. Que tu programa no tenga errores en la escritura es importante, pero más lo es que lo que haga esté bien hecho. Un programa nunca detectará que has sumado dos valores cuando realmente tenías que multiplicarlos, por ejemplo. Éso es un error lógico y ningún programa te lo detectará.

Vistas las funciones var_dump y print_r, dejamos atrás todo el tema de los formularios y volvemos a adentrarnos en el mundo de las funciones, donde empezaremos a revisar la diferencia entre variables locales y globales y abordaremos la recursividad.

Deja una respuesta