7

Cuando una noticia (notice) ocurre, el código puede funcionar, pero es posible que no muestre lo que esperamos.

Creo que estos son los tres tipos de noticias que podemos tener con más frecuencia en PHP.

  • Notice: Undefined variable

  • Notice: Undefined index

  • Notice: Undefined offset

¿Qué significan estas tres noticias y qué es lo que podría generarlas?

Nota:

Esta pregunta existe en SO en Inglés, la idea es tener una buena respuesta también en español que ayude a entender problemas que PHP nos muestra siempre en inglés.

fedorqui
  • 15,850
  • 17
  • 58
  • 112
A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • 3
    Recientemente pregunté en Meta: [¿Es válido realizar preguntas sin mostrar esfuerzo si no es para poner una respuesta propia al mismo tiempo?](https://es.meta.stackoverflow.com/q/2156/83). Parece que hay cierto consenso en que este tipo de preguntas pueden ser útiles para futuros lectores, pero así como se plantean no encajan con las reglas del sitio. Recomiendo acompañarlas de una respuesta wiki, pues tú mismo indicas la respuesta en [so] de donde sacar la información. – fedorqui Jun 16 '17 at 11:46
  • 1
    No es exactamente un error, es un "notice" que es un nivel por debajo. Informa que algo no funcionó del todo bien, pero que no produjo un error o fallo del programa. – vdjkelly Jun 16 '17 at 11:48
  • @fedorqui Gracias por el dato. Aunque señalo que existe la misma discusión en el meta en inglés. Ver el final de la pregunta en inglés. La respuesta que indico está en inglés, se puede traducir y mejorar. La idea también es despertar a la comunidad hispanohablante de SO, la cual me parece un poco lenta al respecto y menos productiva, aunque es más pequeña que la comunidad en inglés. Eso sí, cerrando preguntas la comunidad hispanohablante es super activa, lo cual contribuye mucho más a su empobrecimiento. – A. Cedano Jun 16 '17 at 11:56
  • @vdjkelly En realidad es una noticia o aviso, aunque su constante predifinida es `E_NOTICE`. La `E` quiere decir que es un **E**rror. En alguna parte del [Manual](http://php.net/manual/es/errorfunc.constants.php) leí que era un error. – A. Cedano Jun 16 '17 at 11:58
  • Precisamente ese es el punto que destaco en la publicación en Meta: estas preguntas son utilísimas, pero así como están planteadas las acogemos con los brazos abiertos si van acompañados de la traducción por parte de quien la pregunta. Si no, vienen a ser un "¿alguien puede traducir esto por mí?". – fedorqui Jun 16 '17 at 11:58
  • La respuesta en el sitio en inglés es medio Quijote, ¿realmente queremos traducir eso? Yo contestaría en 3 líneas (una por tipo) y un ejemplo por cada... 6-10 líneas :P – Alvaro Montoro Jun 16 '17 at 12:31
  • Los votos en contra son molestos... pero votar en contra sin decir por qué me parece un acto de cobardía. Bueno, hay _alguien_ en esSO que se dedica a votar en contra cualquier cosa que yo pregunte o responda. – A. Cedano Jun 16 '17 at 13:04
  • 1
    Te diría que esta pregunta "hace daño" :P... Ya sin bromas, tienes dos votos negativos y dos personas que te han puesto comentarios sobre la pregunta y por qué piensan que no es del todo correcta, ¿has pensado que quizás esos dos votos vengan de esas dos personas y por lo tanto sí hayan dicho algo y no haya acto de cobardía alguno? – Alvaro Montoro Jun 16 '17 at 13:08
  • @AlvaroMontoro No creo que quienes hayan votado en contra hayan sido las personas que hasta ahora han comentado, de hecho, no considero que lo comentado amerite un voto negativo. Mi afirmación viene porque incluso la respuesta con más alta reputación en mi historial _también_ tiene un voto negativo y muchas otras preguntas/respuestas que no han sido puestas en entredicho por nadie, a eso me refiero cuando hablo de _cobardía_. Mi costumbre cuando voto en contra es indicarlo en un comentario precedido de -1 `motivo del voto en contra...`El único motivo es quizá la guerra de religiones, digo yo. – A. Cedano Jun 16 '17 at 13:13
  • 2
    @A.Cedano ¿Guerra de religiones? ¿Tú también entraste en el chat equivocado? – Alvaro Montoro Jun 16 '17 at 14:26
  • @AlvaroMontoro Si alguien vota negativamente _cualquier_ movimiento mío aquí en SO puede significar que no le guste mi condición. A eso me refiero con guerra de religiones. Los votos negativos son sistemáticos, _en todo_ y en varias preguntas/respuestas consecutivamente. Es un tema de meta, pero ya que preguntas, respondo. [Esta pregunta es un ejemplo](https://es.stackoverflow.com/q/72719/29967) con un voto en contra realizado junto con otra pregunta también de cierto prestigio de forma consecutiva. – A. Cedano Jun 16 '17 at 14:30
  • asociación: https://stackoverflow.com/q/4261133/1983854 – fedorqui Mar 04 '19 at 15:09

4 Answers4

7

Notice: Undefined variable ocurre cuando usas una variable en una operación, pero dicha variable no se ha definido con anterioridad. Por ejemplo:

<?php
    $a1 = "Hola Caracola";
    print_r($a2); // $a2 no se ha definido antes (a veces causado por errores tipográficos)

Notice: Undefined offset ocurre cuando en un array intentas acceder a un índice numérico que no existe en ese array. Por ejemplo:

<?php
    $miArray = array(1,2,3); // 3 posiciones, índices del 0 al 2
    print_r($miArray[3]);    // Acceso al índice 3 que no existe (PHP empieza en 0)

Notice: Undefined index ocurre cuando en un array intentas acceder a un índice alfanumérico que no existe. Un par de ejemplos:

<?php
    $miArray = array(0 => "Hola", "b" => "Caracola");
    print_r($miArray["a"]); // El índice `a` no existe, sólo `0` o `b` 

    print_r($_GET["parametroQueNoExisteEnElQueryString"]);
Alvaro Montoro
  • 48,157
  • 26
  • 100
  • 179
  • He actualizado la respuesta porque técnicamente no hay diferencia entre array asociativo o no, lo que importa es el índice utilizado para acceder al array. Si no queda claro, lo revierto a la versión anterior. – Alvaro Montoro Jun 16 '17 at 13:05
  • Excelente, mucho más clara que la respuesta en inglés. ¡Gracias! – A. Cedano Jun 16 '17 at 14:40
2

Variable: espacio de memoria que en php referenciamos con un nombre que comienza con $ por ejemplo $edad podria ser una variable para guardar la edad de una persona.

Si se intenta leer (usar) una variable antes de que la misma haya sido definida, o esté fuera de su ámbito de visibilidad PHP arroja "Undefined variable".

Ejemplo donde $b no ha sido mencionada antes de set utilizada:

$a = 1;
if($a == 1){
    $a = $b;
}

Ejemplo donde $b esta siendo referenciada fuera de su ámbito de visibilidad:

$a = 1;
if($a == 1){
  $b = 10;
}
$a = $b;

Con mencionar la variable, la misma ya queda definida, aunque por lo general esta definición va acompañada de una inicialización dado que si definimos una variable es lógico que tenga un valor inicial que tenga sentido. La solución es definir la variable antes de ser usada y dentro del ámbito de visibilidad donde se necesita ejemplo: $b antes o después de $a:

$a = 1;
$b; //Acá ya queda definida pero sin valor inicial
if($a == 1){
...

$a = 1;
$b = 5; //Acá ya queda inicializada (definida + valor inicial)
if($a == 1){
...

Index: es el String que se usa de llave para referenciar un valor en un array asociativo. En este ejemplo nombre y apellido son Index del array asociativo $estudiante:

$estudiante['nombre'] = 'Juan';
$estudiante['apellido'] = "Gomez"; 

Undefined Index significa que el string que estamos pasando com Index al querer leer un valor del array no existe. En el ejemplo el Index domicilio no existe entonces $dom = $estudiante['domicilio']; arroja Undefined Index.

Se puede verificar la existencia de un Index con la función array_key_exists($index);

Offset: es similar a Index pero para arrays comunes donde el índice es un entero que refleja la posición (u offset en inglés) dentro del array. Cuando se intenta leer el valor de un array en una posición que no existe tenemos un Undefined Offset. Ejemplo:

$arr[0] = "caballo";
$arr[1] = "tigre";
$animal = $arr[2]; // Undefined Offset

Una forma de evitar estos errores es verificar que el índice sea mayor a 0 y menor que la cantidad de elementos de array (count($arr));

Juan
  • 5,605
  • 1
  • 9
  • 15
1

pense que estaba con traductor google. Yo uso para verificar arrays, verificando la clave Ejmplo verificar cookiesy si no estan setearla: if (!array_key_exists(COOKIE_ID,$_COOKIE)){Setcookie(COOKIE_ID, 'Y2l1ZGFkYW5v', time() + (3600),'','','', true);}

0

Antes de nada un notice yo lo traduciría mejor como aviso.

Los notice no son errores. Son realmente avisos, y en este caso simplemente te está avisando que dichos indices no existen en el array.

Para evitar que salgan dichos mensajes en la web tienes varias opciones.

Quitar en la configuración de PHP que te muestre los notice

Edita el php.ini y busca la directiva error_reporting

Justo arriba tendrás la explicación de que significa exactamente. En mi caso en producción por ejemplo tengo indicado esto:

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_WARNING & ~E_NOTICE

Ahí le indico que quiero todos los errores, pero que no quiero ni los avisos de funciones deprecated, ni los avisos de strict, ni los warnings, ni los notices.

Deshabilitar los notices en cada fichero php

En cada fichero php, tendrás que ejecutar esta función para que no te muestre dichos errores en la página web que genere el php.

error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_WARNING & ~E_NOTICE);

Programar correctamente detectando si existe o no

En php existe una función llamada isset() que simplemente devuelve si la variable está definida y no es null.

En vez de utilizar directamente un array con un índice como por ejemplo $arr['indice'], puedes crearte una variable que según si existe o no el indice anterior en el array tenga valor o no. Esa variable $indice ya no dará un notice porque siempre tendrá valor.

$indice = ( isset($arr['indice'] ) ? $arr['indice'] : '';

La línea de código anterior equivale también a:

if ( isset($arr['indice'] ) {
   $indice = $arr['indice'];
} else {
   $indice = '':
}
NetVicious
  • 1,205
  • 8
  • 17