"Aviso: variable indefinida", "Aviso: índice indefinido" y "Aviso: desplazamiento indefinido" utilizando PHP

1173

Estoy ejecutando un script PHP y sigo recibiendo errores como:

Aviso: Variable indefinida: my_variable_name en C: \ wamp \ www \ mypath \ index.php en la línea 10

Aviso: índice indefinido: my_index C: \ wamp \ www \ mypath \ index.php en la línea 11

Las líneas 10 y 11 se ven así:

echo "My variable value is: " . $my_variable_name;
echo "My index value is: " . $my_array["my_index"];

¿Cuál es el significado de estos mensajes de error?

¿Por qué aparecen de repente? Solía ​​usar este script durante años y nunca he tenido ningún problema.

¿Cómo los soluciono?


Esta es una pregunta de referencia general para que las personas se vinculen como duplicados, en lugar de tener que explicar el problema una y otra vez. Creo que esto es necesario porque la mayoría de las respuestas del mundo real sobre este tema son muy específicas.

Meta discusión relacionada:

Pekka 웃
fuente
3
la variable podría no haberse inicializado. ¿Estás inicializando la variable desde una publicación o get o cualquier matriz? Si ese es el caso, es posible que no tenga un campo en esa matriz. Que estás accediendo.
Anish Silwal
3
@Pekka 웃 - Noté la edición agregando "y" Aviso: Desplazamiento indefinido "" - ¿No tendría más sentido usar "PHP:" Variable indefinida "," Índice indefinido "," Avisos de "desplazamiento indefinido" "(incluso tomar fuera del PHP, ya que está etiquetado como "php". Además, la URL se corta en and-notice-undef, solo una sugerencia para que la URL no se corte. Quizás incluso eliminar las (demasiadas) citas. OPHP: “Undefined variable/index/offset” notices
Funk Forty Nueve
2
@ Fred Creo que se puede hacer un argumento para ambas variaciones. Existe la posibilidad de que los novatos ingresen a la línea completa, incluido el "Aviso:" en su consulta de búsqueda, que estoy seguro es el principal generador de tráfico para esta pregunta. Si los mensajes no son en su totalidad, es probable que mejore la visibilidad en los motores de búsqueda
Pekka
2
@Pekka 웃 Entiendo. Solo dije eso porque la URL no se cortó antes y ahora sí and-notice-undef. Fue solo una (pocas) sugerencias. Simplemente se repite también siendo Notice: Undefined.
Funk Forty Niner

Respuestas:

1066

Aviso: variable indefinida

De la vasta sabiduría del Manual PHP :

Confiar en el valor predeterminado de una variable no inicializada es problemático en el caso de incluir un archivo en otro que use el mismo nombre de variable. También es un riesgo de seguridad importante con register_globals activado. El error de nivel E_NOTICE se emite en caso de trabajar con variables no inicializadas, sin embargo, no en el caso de agregar elementos a la matriz no inicializada. La construcción del lenguaje isset () se puede utilizar para detectar si una variable ya se ha inicializado. Además y más ideal es la solución de empty () ya que no genera un mensaje de advertencia o error si la variable no se inicializa.

De la documentación de PHP :

No se genera ninguna advertencia si la variable no existe. Eso significa que empty () es esencialmente el conciso equivalente a ! Isset ($ var) || $ var == falso .

Esto significa que usted podría utilizar solamente empty()para determinar si se ha establecido la variable, y además se comprueba la variable frente a la siguiente, 0, 0.0, "", "0", null, falseo [].

Ejemplo:

$o = [];
@$var = ["",0,null,1,2,3,$foo,$o['myIndex']];
array_walk($var, function($v) {
    echo (!isset($v) || $v == false) ? 'true ' : 'false';
    echo ' ' . (empty($v) ? 'true' : 'false');
    echo "\n";
});

Pruebe el fragmento anterior en el editor de PHP en línea 3v4l.org

Aunque PHP no requiere una declaración de variable, la recomienda para evitar algunas vulnerabilidades o errores de seguridad en los que uno olvidaría darle un valor a una variable que se usará más adelante en el script. Lo que PHP hace en el caso de variables no declaradas es emitir un error de muy bajo nivel E_NOTICE, uno que ni siquiera se informa de manera predeterminada, pero el Manual aconseja permitirlo durante el desarrollo.

Formas de lidiar con el problema:

  1. Recomendado: declare sus variables, por ejemplo, cuando intente agregar una cadena a una variable indefinida. O use isset()/ !empty() para verificar si se declaran antes de hacer referencia a ellos, como en:

    //Initializing variable
    $value = ""; //Initialization value; Examples
                 //"" When you want to append stuff later
                 //0  When you want to add numbers later
    //isset()
    $value = isset($_POST['value']) ? $_POST['value'] : '';
    //empty()
    $value = !empty($_POST['value']) ? $_POST['value'] : '';
    

    Esto se ha vuelto mucho más limpio a partir de PHP 7.0, ahora puede usar el operador de fusión nula :

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Establezca un controlador de errores personalizado para E_NOTICE y redirija los mensajes fuera de la salida estándar (tal vez a un archivo de registro):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
  3. Inhabilite E_NOTICE de los informes. Una forma rápida de excluir solo E_NOTICEes:

    error_reporting( error_reporting() & ~E_NOTICE )
  4. Suprima el error con el operador @ .

Nota: Se recomienda encarecidamente implementar solo el punto 1.

Aviso: índice indefinido / desplazamiento indefinido

Este aviso aparece cuando usted (o PHP) intenta acceder a un índice indefinido de una matriz.

Formas de lidiar con el problema:

  1. Compruebe si el índice existe antes de acceder a él. Para esto puedes usar isset()o array_key_exists():

    //isset()
    $value = isset($array['my_index']) ? $array['my_index'] : '';
    //array_key_exists()
    $value = array_key_exists('my_index', $array) ? $array['my_index'] : '';
    
  2. La construcción del lenguaje list()puede generar esto cuando intenta acceder a un índice de matriz que no existe:

    list($a, $b) = array(0 => 'a');
    //or
    list($one, $two) = explode(',', 'test string');
    

Se utilizan dos variables para acceder a dos elementos de la matriz, sin embargo, solo hay un elemento de la matriz, índice 0, por lo que esto generará:

Aviso: desplazamiento indefinido: 1

$_POST/ $_GET/ $_SESSIONvariable

Los avisos anteriores aparecen a menudo cuando se trabaja con $_POST, $_GETo $_SESSION. Para $_POSTy $_GETsolo tiene que verificar si el índice existe o no antes de usarlos. Para ello $_SESSION, debe asegurarse de haber iniciado la sesión session_start()y de que el índice también exista.

También tenga en cuenta que las 3 variables son superglobales y son mayúsculas.

Relacionado:

Rizier123
fuente
77
@ dieselpower44 Un par de ideas: el "operador de cierre" ( @) tiene algunos problemas de rendimiento. Además, dado que suprime todos los errores dentro de un alcance particular, usarlo sin cuidado podría enmascarar los mensajes que desearía haber visto.
IMSoP
66
Ocultar los problemas NO es la forma de lidiar con los problemas. Los elementos n. ° 2 ... n. ° 4 solo se pueden usar en servidores de producción, no en general.
Salman A
1
¿Es posible cerrar el mensaje en línea (no en el controlador) cuando también se utiliza un controlador de error personalizado? $var = @$_GET['nonexisting'];todavía causa aviso ..
Alph.Dev
18
¿Por qué se recomienda usar 1. en $value = isset($_POST['value']) ? $_POST['value'] : '';lugar de usar 4. $value = @$_POST['value'];?
forsvunnet
@twistedpixel Esas 4 formas son independientes, esa no es una guía de 4 pasos. Entonces, si eligió usar la forma 4, eso significa que no implementó las primeras 3 formas, por lo que aún no eliminó ningún error.
Aycan Yaşıt
141

Prueba estos

P1: este aviso significa que $ varname no está definido en el alcance actual del script.

P2: El uso de las condiciones isset (), empty () antes de usar cualquier variable sospechosa funciona bien.

// recommended solution for recent PHP versions
$user_name = $_SESSION['user_name'] ?? '';

// pre-7 PHP versions
$user_name = '';
if (!empty($_SESSION['user_name'])) {
     $user_name = $_SESSION['user_name'];
}

O, como una solución rápida y sucia:

// not the best solution, but works
// in your php setting use, it helps hiding site wide notices
error_reporting(E_ALL ^ E_NOTICE);

Nota sobre las sesiones:

Ish
fuente
Si se usa E_NOTICEdesde el php.iniarchivo de configuración, hagaerror_reporting = (E_ALL & ~E_NOTICE)
ahmd0
De la respuesta anterior, he intentado isset, array_key_exists pero esos no funcionaron. Intenté tu respuesta, .empty (), y funciona. ¡Muchas gracias!
Ewef
63

Operador de visualización de errores@

Para avisos no deseados y redundantes, uno podría usar el @operador dedicado para » ocultar « mensajes de índice / variable indefinidos.

$var = @($_GET["optional_param"]);
  • Esto generalmente se desaconseja. Los recién llegados tienden a abusar de él.
  • Es muy inapropiado para el código en lo profundo de la lógica de la aplicación (ignorando variables no declaradas donde no debería), por ejemplo, para parámetros de función o en bucles.
  • Hay uno al revés sobre el isset?:o ??super-supresión sin embargo. Los avisos aún pueden registrarse. Y uno puede resucitar @avisos ocultos con:set_error_handler("var_dump");
    • Además, no debe usar / recomendar habitualmente if (isset($_POST["shubmit"]))en su código inicial.
    • Los recién llegados no detectarán tales errores tipográficos. Simplemente te priva de avisos de PHP para esos mismos casos. Agregar @o issetsolo después de verificar la funcionalidad.
    • Arregla la causa primero. No los avisos.

  • @es principalmente aceptable para $_GET/ $_POSTparámetros de entrada, específicamente si son opcionales .

Y dado que esto cubre la mayoría de estas preguntas, ampliemos las causas más comunes:

$_GET/ $_POST/ $_REQUESTentrada indefinida

  • Lo primero que debe hacer al encontrar un índice / desplazamiento indefinido es verificar los errores tipográficos:
    $count = $_GET["whatnow?"];

    • ¿Es este un nombre clave esperado y presente en cada solicitud de página?
    • Los nombres de variables y las indicaciones de matriz distinguen entre mayúsculas y minúsculas en PHP.
  • En segundo lugar, si el aviso no tiene una causa obvia, utilice var_dumpo print_rpara verificar todas las matrices de entrada para su contenido actual:

    var_dump($_GET);
    var_dump($_POST);
    //print_r($_REQUEST);
    

    Ambos revelarán si su secuencia de comandos se invocó con la derecha o con algún parámetro.

  • Alternativamente, use adicionalmente las herramientas deF12 su navegador ( ) e inspeccione la pestaña de red para conocer las solicitudes y los parámetros:

    herramientas de desarrollador del navegador / pestaña de red

    Los parámetros POST y la entrada GET se mostrarán por separado.

  • Para $_GETlos parámetros que también puedes vistazo a la QUERY_STRINGde

    print_r($_SERVER);

    PHP tiene algunas reglas para fusionar nombres de parámetros no estándar en las superglobales. Apache podría reescribir también. También puede ver los $_COOKIESencabezados de solicitud HTTP sin procesar y otros encabezados de esa manera.

  • Más obviamente, mira la barra de direcciones de tu navegador para ver los parámetros GET :

    http://example.org/script.php?id=5&sort=desc

    Los name=valuepares después del ?signo de interrogación son los parámetros de su consulta (GET). Por lo tanto, esta URL solo podría producir $_GET["id"]y $_GET["sort"].

  • Finalmente verifique sus declaraciones <form>y<input> , si espera un parámetro pero no recibe ninguno.

    • Asegúrese de que cada entrada requerida tenga un <input name=FOO>
    • El atributo id=o title=no es suficiente.
    • Debe method=POSTformarse una forma $_POST.
    • Mientras que a method=GET(o dejarlo fuera) produciría $_GETvariables.
    • También es posible que un formulario se suministre a action=script.php?get=paramtravés de $ _GET y los method=POSTcampos restantes en $ _POST junto.
    • Con las configuraciones modernas de PHP (≥ 5.6) se ha vuelto factible (no está de moda) usarlo $_REQUEST['vars']nuevamente, lo que combina los parámetros GET y POST.
  • Si está empleando mod_rewrite, entonces debe verificar tanto access.logcomo habilitar RewriteLogpara descubrir los parámetros ausentes.

$_FILES

  • Las mismas verificaciones de cordura se aplican a las cargas de archivos y $_FILES["formname"].
  • Además, verifique enctype=multipart/form-data
  • Así como method=POSTen tu <form>declaración.
  • Ver también: PHP Error de índice indefinido $ _FILES?

$_COOKIE

  • La $_COOKIEmatriz nunca se llena inmediatamente después setcookie(), sino solo en cualquier solicitud HTTP de seguimiento.
  • Además, su validez agota el tiempo de espera, podrían limitarse a subdominios o rutas individuales, y el usuario y el navegador pueden simplemente rechazarlos o eliminarlos.
mario
fuente
2
Si tiene curiosidad sobre el impacto en el rendimiento, este artículo lo resume bien, derickrethans.nl/… .
Gajus
@GajusKuizinas Se han producido algunos cambios desde 2009, en particular php.net/ChangeLog-5.php#5.4.0 cambia drásticamente el resultado (consulte "Motor Zend, rendimiento" y "operador (silencio)").
mario
Gracias @mario, interesante. Ahora, si alguien fue lo suficientemente bueno como para comparar los dos ... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs Según esta prueba, parecen ser idénticos (observe que la escala cambia).
Gajus
47

Generalmente debido a la "mala programación" y la posibilidad de errores ahora o más tarde.

  1. Si es un error, primero haga una asignación adecuada a la variable: $ varname = 0;
  2. Si realmente solo se define a veces, pruébelo: if (isset($varname))antes de usarlo
  3. Si es porque lo deletreaste mal, solo corrígelo
  4. Tal vez incluso apague las advertencias en su configuración PHP
Erik
fuente
55
Por favor, no apague las advertencias. En lenguajes más estrictos, a menudo significan "puede haber un error, es mejor que revises esta línea dos veces" - en un lenguaje tan permisivo como PHP, a menudo significan "este código es una basura y está plagado de errores de manera propagable; intentaré hacer que algún sentido, pero es mejor que arregles esto lo antes posible ".
55
Aunque estoy de acuerdo con los primeros tres puntos, el # 4 simplemente está equivocado. Ocultar un problema no hará que desaparezca, e incluso podría causar más problemas en el futuro.
Valentin Flachsel el
1
@Freek es absolutamente cierto, pero en algunos escenarios (script comprado, cero conocimiento técnico, lo necesito para mañana ...) es la solución de cinta adhesiva, realmente mala, que siempre necesita enfatizarse, pero una opción
Pekka
La cinta adhesiva es buena ... a veces. Históricamente, las advertencias se han desactivado en la configuración estándar de PHP, pero la configuración predeterminada se ha vuelto más estricta. Lástima que muchos vuelvan a la configuración anterior, para no molestar a los clientes.
Erik
41

Significa que está probando, evaluando o imprimiendo una variable a la que aún no ha asignado nada. Significa que tiene un error tipográfico o que necesita verificar que la variable se haya inicializado en algo primero. Verifique sus rutas lógicas, puede establecerse en una ruta pero no en otra.

DGM
fuente
34

No quería deshabilitar el aviso porque es útil, pero quería evitar escribir demasiado.

Mi solución fue esta función:

function ifexists($varname)
{
  return(isset($$varname)?$varname:null);
}

Entonces, si quiero hacer referencia a $ name y echo si existe, simplemente escribo:

<?=ifexists('name')?>

Para elementos de matriz:

function ifexistsidx($var,$index)
{
  return(isset($var[$index])?$var[$index]:null);
}

En la página si quiero referirme a $ _REQUEST ['nombre']:

<?=ifexistsidx($_REQUEST,'name')?>
Ferenci Zoltán László
fuente
2
Su función ifexists () no funciona para mí en PHP 5.3. Las variables de la persona que llama no están disponibles en el ámbito local de la función (ver Ámbito variable ), a menos que sean Superglobales o usted juegue con $ GLOBALS , por $foo = "BABAR"; ifexists('foo');lo que en general devolverá nulo. (Las cursivas son capítulos de php.net.)
skierpage
ahora recibirás "hola de" ... ¿cuál es el punto? solo verifique el valorif( !empty($user) and !empty($location) ) echo "hello $user ..."
gcb
27

La mejor manera de obtener una cadena de entrada es:

$value = filter_input(INPUT_POST, 'value');

Esta línea es casi equivalente a:

if (!isset($_POST['value'])) {
    $value = null;
} elseif (is_array($_POST['value'])) {
    $value = false;
} else {
    $value = $_POST['value'];
}

Si absolutamente desea un valor de cadena , al igual que:

$value = (string)filter_input(INPUT_POST, 'value');
mpyw
fuente
25

Es porque la variable '$ user_location' no se está definiendo. Si está utilizando un bucle if dentro del cual está declarando la variable '$ user_location', también debe tener un bucle else y definir el mismo. Por ejemplo:

$a=10;
if($a==5) { $user_location='Paris';} else { }
echo $user_location;

El código anterior creará un error como el bucle if no está satisfecho y en el bucle else '$ user_location' no se definió. Todavía se le pidió a PHP que repitiera la variable. Entonces, para modificar el código, debe hacer lo siguiente:

$a=10;
if($a==5) { $user_location='Paris';} else { $user_location='SOMETHING OR BLANK'; }
echo $user_location;
Roger
fuente
25

En respuesta a "" ¿Por qué aparecen de repente? Solía ​​usar este script durante años y nunca tuve ningún problema ".

Es muy común que la mayoría de los sitios operen bajo el informe de error "predeterminado" de "Mostrar todos los errores, pero no 'avisos' y 'obsoletos'". Esto se establecerá en php.ini y se aplicará a todos los sitios en el servidor. Esto significa que esos "avisos" utilizados en los ejemplos serán suprimidos (ocultos) mientras que otros errores, considerados más críticos, serán mostrados / grabados.

La otra configuración crítica es que los errores pueden estar ocultos (es decir, display_errorsconfigurados en "apagado" o "syslog").

Lo que habrá sucedido en este caso es que error_reportingse modificó para mostrar también avisos (como en los ejemplos) y / o se cambió la configuración a la display_errorspantalla (en lugar de suprimirlos / registrarlos).

¿Por qué han cambiado?

La respuesta obvia / más simple es que alguien ajustó cualquiera de estas configuraciones en php.ini, o una versión mejorada de PHP ahora está usando un php.ini diferente al anterior. Ese es el primer lugar para buscar.

Sin embargo, también es posible anular esta configuración en

  • .htconf (configuración del servidor web, incluidos vhosts y subconfiguraciones) *
  • .htaccess
  • en el código php en sí

y cualquiera de estos también podría haber sido cambiado.

También existe la complicación adicional de que la configuración del servidor web puede habilitar / deshabilitar las directivas .htaccess, por lo que si tiene directivas en .htaccess que de repente comienzan / dejan de funcionar, entonces debe verificar eso.

(.htconf / .htaccess suponen que se está ejecutando como apache. Si ejecuta la línea de comandos, esto no se aplicará; si ejecuta IIS u otro servidor web, deberá verificar esas configuraciones en consecuencia)

Resumen

  • Las directivas check error_reportingy display_errorsphp en php.ini no han cambiado, o que no esté utilizando un php.ini diferente al anterior.
  • Las directivas check error_reportingy display_errorsphp en .htconf (o vhosts, etc.) no han cambiado
  • Las directivas check error_reportingy display_errorsphp en .htaccess no han cambiado
  • Si tiene una directiva en .htaccess, verifique si todavía están permitidas en el archivo .htconf
  • Finalmente revise su código; posiblemente una biblioteca no relacionada; para ver si error_reportingy display_errorsdirectivas de PHP se han establecido allí.
Robbie
fuente
20

la solución rápida es asignar su variable a nulo en la parte superior de su código

$user_location = null;
Shahin Mammadzada
fuente
16

Solía ​​maldecir este error, pero puede ser útil recordarle que escape de la entrada del usuario.

Por ejemplo, si pensabas que esto era inteligente, código abreviado:

// Echo whatever the hell this is
<?=$_POST['something']?>

...¡Piensa otra vez! Una mejor solución es:

// If this is set, echo a filtered version
<?=isset($_POST['something']) ? html($_POST['something']) : ''?>

(Utilizo una html()función personalizada para escapar de los personajes, su kilometraje puede variar)

rybo111
fuente
15

En PHP 7.0 ahora es posible usar un operador de fusión nulo:

echo "My index value is: " . ($my_array["my_index"] ?? '');

Igual a:

echo "My index value is: " . (isset($my_array["my_index"]) ? $my_array["my_index"] : '');

PHP manual PHP 7.0

elpiel
fuente
Esto también funciona bien en las declaraciones if. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
un codificador
Su código es en realidad un buen error pasado por alto: ?? - solo comprueba isset()si se aprueba is_array(), lo cual es un comportamiento booleano e inesperado.
elpiel
14

Uso todo el tiempo propia función útil exst () que declara variables automáticamente.

Tu código será -

$greeting = "Hello, ".exst($user_name, 'Visitor')." from ".exst($user_location);


/** 
 * Function exst() - Checks if the variable has been set 
 * (copy/paste it in any place of your code)
 * 
 * If the variable is set and not empty returns the variable (no transformation)
 * If the variable is not set or empty, returns the $default value
 *
 * @param  mixed $var
 * @param  mixed $default
 * 
 * @return mixed 
 */

function exst( & $var, $default = "")
{
    $t = "";
    if ( !isset($var)  || !$var ) {
        if (isset($default) && $default != "") $t = $default;
    }
    else  {  
        $t = $var;
    }
    if (is_string($t)) $t = trim($t);
    return $t;
}
usuario2253362
fuente
14

En un lenguaje muy simple .
El error es que está utilizando una variable $user_locationque no ha definido anteriormente y que no tiene ningún valor, por lo que le recomiendo que declare esta variable antes de usarla , por ejemplo:


$user_location = '';
O
$user_location = 'Los Angles';
Este es un error muy común que puede enfrentar, así que no se preocupe, simplemente declare la variable y disfrute de la codificación .

Rishabh Seth
fuente
8

¿Por qué no mantener las cosas simples?

<?php
error_reporting(E_ALL); // making sure all notices are on

function idxVal(&$var, $default = null) {
         return empty($var) ? $var = $default : $var;
  }

echo idxVal($arr['test']);         // returns null without any notice
echo idxVal($arr['hey ho'], 'yo'); // returns yo and assigns it to array index, nice

?>
gts
fuente
8

¿POR QUÉ ESTÁ PASANDO ESTO?

Con el tiempo, PHP se ha convertido en un lenguaje más centrado en la seguridad. La configuración que solía estar desactivada de manera predeterminada ahora se activa de manera predeterminada. Un ejemplo perfecto de esto es E_STRICT, que se activó por defecto a partir de PHP 5.4.0 .

Además, de acuerdo con la documentación de PHP, de forma predeterminada, E_NOTICEestá deshabilitado en php.ini. Los documentos PHP recomiendan activarlo con fines de depuración . Sin embargo, cuando descargo PHP desde el repositorio de Ubuntu, y desde la pila de Windows de BitNami, veo algo más.

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

Tenga en cuenta que en error_reportingrealidad se establece en el valor de producción de forma predeterminada, no en el valor "predeterminado" de forma predeterminada. Esto es algo confuso y no está documentado fuera de php.ini, por lo que no lo he validado en otras distribuciones.

Sin embargo, para responder a su pregunta, este error aparece ahora cuando no apareció antes porque:

  1. Instaló PHP y la nueva configuración predeterminada está algo mal documentada pero no excluye E_NOTICE.

  2. E_NOTICEadvertencias como variables indefinidas e índices indefinidos realmente ayudan a que su código sea más limpio y seguro. Puedo decirte que, hace años, mantener E_NOTICEhabilitado me obligó a declarar mis variables. Hizo MUCHO más fácil aprender C, no declarar variables es mucho más molesto.

¿QUÉ PUEDO HACER AL RESPECTO?

  1. Apague E_NOTICEcopiando el "Valor predeterminado" E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATEDy reemplazándolo con lo que actualmente no está comentado después del inicio de sesión igual error_reporting =. Reinicie Apache o PHP si usa CGI o FPM. Asegúrese de estar editando el php.ini "correcto". El correcto será Apache si está ejecutando PHP con Apache, fpm o php-fpm si está ejecutando PHP-FPM, cgi si está ejecutando PHP-CGI, etc. Este no es el método recomendado, pero si tiene código heredado ser extremadamente difícil de editar, entonces podría ser tu mejor apuesta.

  2. Desactiva E_NOTICEel nivel de archivo o carpeta. Esto podría ser preferible si tiene algún código heredado pero de lo contrario quiere hacer las cosas de la manera "correcta". Para hacer esto, debe consultar Apache2, Nginx o el servidor que elija. En Apache, usarías php_valuedentro de <Directory>.

  3. Reescribe tu código para estar más limpio. Si necesita hacer esto mientras se muda a un entorno de producción o no quiere que alguien vea sus errores, asegúrese de deshabilitar cualquier visualización de errores y solo registrar sus errores (vea display_errorsy log_errorsen php.ini y la configuración de su servidor) .

Para ampliar en la opción 3: Este es el ideal. Si puedes seguir esta ruta, deberías. Si no va por esta ruta inicialmente, considere mover esta ruta eventualmente probando su código en un entorno de desarrollo. Mientras lo hace, deshágase ~E_STRICTy ~E_DEPRECATEDvea qué podría salir mal en el futuro. Verá MUCHOS errores desconocidos, pero evitará que tenga problemas desagradables cuando necesite actualizar PHP en el futuro.

¿Qué significan los errores?

Undefined variable: my_variable_name- Esto ocurre cuando una variable no se ha definido antes de su uso. Cuando se ejecuta el script PHP, internamente solo asume un valor nulo. Sin embargo, ¿en qué escenario necesitaría verificar una variable antes de definirla? En última instancia, este es un argumento para el "código descuidado". Como desarrollador, puedo decirle que me encanta cuando veo un proyecto de código abierto donde las variables se definen tan alto en sus alcances como se pueden definir. Hace que sea más fácil saber qué variables aparecerán en el futuro y hace que sea más fácil leer / aprender el código.

function foo()
{
    $my_variable_name = '';

    //....

    if ($my_variable_name) {
        // perform some logic
    }
}

Undefined index: my_index- Esto ocurre cuando intenta acceder a un valor en una matriz y no existe. Para evitar este error, realice una verificación condicional.

// verbose way - generally better
if (isset($my_array['my_index'])) {
    echo "My index value is: " . $my_array['my_index'];
}

// non-verbose ternary example - I use this sometimes for small rules.
$my_index_val = isset($my_array['my_index'])?$my_array['my_index']:'(undefined)';
echo "My index value is: " . $my_index_val;   

Otra opción es declarar una matriz vacía en la parte superior de su función. Esto no siempre es posible.

$my_array = array(
    'my_index' => ''
);

//...

$my_array['my_index'] = 'new string';

(consejo adicional)

  • Cuando me encontraba con estos y otros problemas, utilicé NetBeans IDE (gratis) y me dio una gran cantidad de advertencias y avisos. Algunos de ellos ofrecen consejos muy útiles. Esto no es un requisito, y ya no uso IDEs excepto para proyectos grandes. Soy más una vimpersona en estos días :).
smcjones
fuente
6

índice indefinido significa en una matriz que solicitó un índice de matriz no disponible, por ejemplo

<?php 

$newArray[] = {1,2,3,4,5};
print_r($newArray[5]);

?>

variable indefinida significa que ha utilizado una variable completamente no existente o que no está definida o inicializada con ese nombre, por ejemplo

<?php print_r($myvar); ?>

desplazamiento indefinido significa en la matriz que ha solicitado una clave no existente. Y la solución para esto es verificar antes de usar

php> echo array_key_exists(1, $myarray);
Sintayehu Abaynhe
fuente
4

Con respecto a esta parte de la pregunta:

¿Por qué aparecen de repente? Solía ​​usar este script durante años y nunca he tenido ningún problema.

No hay respuestas definitivas, pero aquí hay algunas explicaciones posibles de por qué la configuración puede cambiar 'repentinamente':

  1. Ha actualizado PHP a una versión más nueva que puede tener otros valores predeterminados para error_reporting, display_errors u otras configuraciones relevantes.

  2. Ha eliminado o introducido algún código (posiblemente en una dependencia) que establece configuraciones relevantes en tiempo de ejecución usando ini_set()o error_reporting()(búsquelas en el código)

  3. Cambió la configuración del servidor web (suponiendo que apache aquí): los .htaccessarchivos y las configuraciones de vhost también pueden manipular la configuración de php.

  4. Por lo general, los avisos no se muestran / informan (consulte el manual de PHP ), por lo que es posible que al configurar el servidor, el archivo php.ini no se pueda cargar por alguna razón (¿permisos de archivo?) Y usted estaba en la configuración predeterminada . Más tarde, el 'error' se resolvió (por accidente) y ahora PUEDE cargar el archivo php.ini correcto con el conjunto de informes de error para mostrar avisos.

Wouter de Winter
fuente
3

Si trabaja con clases, debe asegurarse de hacer referencia a las variables miembro utilizando $this:

class Person
{
    protected $firstName;
    protected $lastName;

    public function setFullName($first, $last)
    {
        // Correct
        $this->firstName = $first;

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}
John Conde
fuente
3

Otra razón por la que se arrojará un aviso de índice indefinido sería que se omitió una columna de una consulta de base de datos.

Es decir:

$query = "SELECT col1 FROM table WHERE col_x = ?";

Luego intenta acceder a más columnas / filas dentro de un bucle.

Es decir:

print_r($row['col1']);
print_r($row['col2']); // undefined index thrown

o en un whilebucle:

while( $row = fetching_function($query) ) {

    echo $row['col1'];
    echo "<br>";
    echo $row['col2']; // undefined index thrown
    echo "<br>";
    echo $row['col3']; // undefined index thrown

}

Algo más que debe tenerse en cuenta es que en un * NIX OS y Mac OS X, las cosas distinguen entre mayúsculas y minúsculas.

Consulte las siguientes preguntas y respuestas sobre la pila:

Fred -ii-
fuente
3

Usar un ternario es simple, legible y limpio:

Pre PHP 7
Asigne una variable al valor de otra variable si está establecida, de lo contrario, asignenull(o el valor predeterminado que necesite):

$newVariable = isset($thePotentialData) ? $thePotentialData : null;

PHP 7+
Lo mismo, excepto que usa el Operador de fusión nula . Ya no es necesario llamar, isset()ya que está integrado, y no es necesario proporcionar la variable para devolver, ya que se supone que devuelve el valor de la variable que se está comprobando:

$newVariable = $thePotentialData ?? null;

Ambos detendrán los Avisos de la pregunta de OP, y ambos son el equivalente exacto de:

if (isset($thePotentialData)) {
    $newVariable = $thePotentialData;
} else {
    $newVariable = null;
}

 
Si no necesita establecer una nueva variable, puede usar directamente el valor devuelto del ternario, como con echo, argumentos de función, etc.

Eco:

echo 'Your name is: ' . isset($name) ? $name : 'You did not provide one';

Función:

$foreName = getForeName(isset($userId) ? $userId : null);

function getForeName($userId)
{
    if ($userId === null) {
        // Etc
    }
}

Lo anterior funcionará de la misma manera con las matrices, incluidas las sesiones, etc., reemplazando la variable que se verifica con, por ejemplo,
$_SESSION['checkMe']
o con la cantidad de niveles que necesite, por ejemplo:
$clients['personal']['address']['postcode']


 

Supresión:

Es posible suprimir los Avisos PHP con @o reducir su nivel de informe de errores, pero no soluciona el problema , simplemente evita que se informe en el registro de errores. Esto significa que su código todavía intentó usar una variable que no se configuró, lo que puede significar o no que algo no funcione según lo previsto, dependiendo de cuán crucial sea el valor faltante.

Realmente debería verificar este problema y manejarlo adecuadamente, ya sea sirviendo un mensaje diferente o incluso simplemente devolviendo un valor nulo para todo lo demás para identificar el estado preciso.

Si solo le importa que el Aviso no esté en el registro de errores, entonces, como opción, simplemente puede ignorar el registro de errores.

James
fuente
1

Una causa común de una variable que no existe después de enviar un formulario HTML es que el elemento del formulario no está contenido en una <form>etiqueta:

Ejemplo: elemento no contenido dentro del <form>

<form action="example.php" method="post">
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>

<select name="choice">
    <option value="choice1">choice 1</option>
    <option value="choice2">choice 2</option>
    <option value="choice3">choice 3</option>
    <option value="choice4">choice 4</option>
</select>

Ejemplo: Elemento ahora contenido dentro del <form>

<form action="example.php" method="post">
    <select name="choice">
        <option value="choice1">choice 1</option>
        <option value="choice2">choice 2</option>
        <option value="choice3">choice 3</option>
        <option value="choice4">choice 4</option>
    </select>
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>
John Conde
fuente
0

Probablemente estaba usando una versión anterior de PHP hasta ahora y ahora actualizó PHP, esa es la razón por la que funcionó sin ningún error hasta ahora desde hace años. hasta PHP4 no hubo error si está utilizando una variable sin definirla, pero a partir de PHP5 en adelante arroja errores para los códigos como se menciona en la pregunta.

phvish
fuente
0

Cuando se trata de archivos, se requiere un enctype adecuado y un método POST, que desencadenará un aviso de índice indefinido si ninguno de los dos se incluye en el formulario.

El manual establece la siguiente sintaxis básica:

HTML

<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

PHP

<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

?>

Referencia:

Funk Forty Niner
fuente
0

Hice una pregunta sobre esto y me remitieron a esta publicación con el mensaje:

Esta pregunta ya tiene una respuesta aquí:

"Aviso: variable indefinida", "Aviso: índice indefinido" y "Aviso: desplazamiento indefinido" utilizando PHP

Estoy compartiendo mi pregunta y solución aquí:

Este es el error:

ingrese la descripción de la imagen aquí

La línea 154 es el problema. Esto es lo que tengo en la línea 154:

153    foreach($cities as $key => $city){
154        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){

Creo que el problema es que estoy escribiendo condiciones para la variable $city, que no es la clave sino el valor $key => $city. Primero, ¿podría confirmar si esa es la causa de la advertencia? Segundo, si ese es el problema, ¿por qué no puedo escribir una condición basada en el valor? ¿Tiene que estar con la clave que necesito para escribir la condición?

ACTUALIZACIÓN 1: El problema es que, al ejecutar $citiesCounterArray[$key], a veces $keycorresponde a una clave que no existe en la $citiesCounterArraymatriz, pero que no siempre es el caso en función de los datos de mi bucle. Lo que necesito es establecer una condición para que si $keyexiste en la matriz, luego ejecute el código, de lo contrario, omítalo.

ACTUALIZACIÓN 2: Así es como lo arreglé usando array_key_exists():

foreach($cities as $key => $city){
    if(array_key_exists($key, $citiesCounterArray)){
        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){
Jaime Montoya
fuente
0

Estos errores ocurren cada vez que usamos una variable que no está configurada.

La mejor manera de lidiar con esto es establecer informes de errores durante el desarrollo.

Para configurar el informe de errores en:

ini_set('error_reporting', 'on');
ini_set('display_errors', 'on');
error_reporting(E_ALL);

En los servidores de producción, el informe de errores está desactivado, por lo tanto, no obtenemos estos errores.

En el servidor de desarrollo, sin embargo, podemos establecer informes de errores.

Para deshacerse de este error, vemos el siguiente ejemplo:

if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

Podemos inicializar las variables NULLantes de asignar sus valores o usarlos.

Entonces, podemos modificar el código como:

$test = NULL;
if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

Esto no perturbará la lógica de ningún programa y no generará un Aviso incluso si $testno tiene valor.

Entonces, básicamente, siempre es mejor establecer informes de errores en ON para el desarrollo.

Y arregla todos los errores.

Y en la producción, los informes de errores deben estar desactivados.

Alumno
fuente
-1

Esos avisos se deben a que no tiene la variable utilizada definedy la my_indexclave no estaba presente en la $my_arrayvariable.

Esos avisos se activaron cada vez, porque su codeno es correcto, pero probablemente no tenía el informe de avisos activado .

Resuelve los errores:

$my_variable_name = "Variable name"; // defining variable
echo "My variable value is: " . $my_variable_name;

if(isset($my_array["my_index"])){
    echo "My index value is: " . $my_array["my_index"]; // check if my_index is set 
}

Otra forma de sacar esto:

ini_set("error_reporting", false)
Andrei Todorut
fuente
-2

En PHP necesitas un puño para definir la variable después de eso puedes usarla.
¡Podemos comprobar si la variable está definida o no de manera muy eficiente!

//If you only want to check variable has value and value has true and false value.
//But variable must be defined first.

if($my_variable_name){

}

//If you want to check variable is define or undefine
//Isset() does not check that variable has true or false value
//But it check null value of variable
if(isset($my_variable_name)){

}

Explicación simple

//It will work with :- true,false,NULL
$defineVarialbe = false;
if($defineVarialbe){
    echo "true";
}else{
    echo "false";
}

//It will check variable is define or not and variable has null value.
if(isset($unDefineVarialbe)){
    echo "true";
}else{
    echo "false";
}
Goswami Manish
fuente