Question PHP: "Notice: Variable indéfinie", "Notice: Indéfini index", et "Notice: Offset non défini"


Je cours un script PHP, et continue d'obtenir des erreurs comme:

Remarque: Variable non définie: my_variable_name dans C: \ wamp \ www \ mypath \ index.php à la ligne 10

Remarque: Indéfini index: mon_index C: \ wamp \ www \ mypath \ index.php à la ligne 11

Les lignes 10 et 11 ressemblent à ceci:

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

Que signifient ces erreurs?

Pourquoi apparaissent-ils tout d'un coup? J'avais l'habitude d'utiliser ce script pendant des années et je n'ai jamais eu aucun problème.

Que dois-je faire pour les réparer?

Ceci est une question de référence générale au lieu de devoir expliquer le problème encore et encore. Je pense que c'est nécessaire parce que la plupart des réponses du monde réel sur cette question sont très spécifiques.

Meta discussion connexe:


948


origine


Réponses:


Remarque: variable indéfinie

De la vaste sagesse de la Manuel PHP:

Compter sur la valeur par défaut d'une variable non initialisée est problématique dans le cas de l'inclusion d'un fichier dans un autre qui utilise le même nom de variable. C'est aussi un grand risque de sécurité avec register_globals allumé. E_NOTICE erreur de niveau est émise en cas de travail avec des variables non initialisées, mais pas dans le cas d'ajouter des éléments au tableau non initialisé. isset () La construction de langage peut être utilisée pour détecter si une variable a déjà été initialisée. En outre et plus idéal est la solution de vide() car il ne génère pas d'avertissement ou de message d'erreur si la variable n'est pas initialisée.

De Documentation PHP:

Aucun avertissement n'est généré si la variable n'existe pas. Cela signifie       vide() est essentiellement l'équivalent concis à ! isset ($ var) || $ var      == false.

Cela signifie que vous ne pouvez utiliser que empty() pour déterminer si la variable est définie, et en plus il vérifie la variable par rapport à ce qui suit, 0,"",null.

Exemple:

$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";
});

Testez l'extrait ci-dessus dans le 3v4l.org éditeur en ligne de PHP

Bien que PHP ne nécessite pas de déclaration de variable, il le recommande afin d'éviter certaines failles de sécurité ou bogues où l'on oublie de donner une valeur à une variable qui sera utilisée plus tard dans le script. Ce que PHP fait dans le cas de variables non déclarées est une erreur de très bas niveau, E_NOTICE, celui qui n'est même pas signalé par défaut, mais le Manuel conseille de permettre pendant le développement.

Façons de traiter le problème:

  1. Conseillé: Déclarez vos variables, par exemple lorsque vous essayez d'ajouter une chaîne à une variable indéfinie. Ou utiliser isset() / !empty()  pour vérifier si elles sont déclarées avant de les référencer, comme dans:

    //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'] : '';
    

    Ceci est devenu beaucoup plus propre à partir de PHP 7.0, maintenant vous pouvez utiliser le opérateur de coalesce null:

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Définir un gestionnaire d'erreur personnalisé pour E_NOTICE et rediriger les messages à partir de la sortie standard (peut-être dans un fichier journal):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
    
  3. Désactivez E_NOTICE dans les rapports. Un moyen rapide d'exclure juste E_NOTICE est:

    error_reporting( error_reporting() & ~E_NOTICE )
    
  4. Supprimer l'erreur avec le @ opérateur.

Remarque: Il est fortement recommandé d'implémenter uniquement le point 1.

Avis: Index non défini / Offset non défini

Cet avis apparaît lorsque vous (ou PHP) essayez d'accéder à un index indéfini d'un tableau.

Façons de traiter le problème:

  1. Vérifiez si l'index existe avant d'y accéder. Pour cela, vous pouvez utiliser isset() ou 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 construction de la langue list() peut générer ceci quand il tente d'accéder à un index de tableau qui n'existe pas:

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

Deux variables sont utilisées pour accéder à deux éléments de tableau, mais il n'y a qu'un seul élément de tableau, index 0Cela va donc générer:

Avis: Offset non défini: 1

$_POST / $_GET / $_SESSION variable

Les avis ci-dessus apparaissent souvent lorsque vous travaillez avec $_POST, $_GET ou $_SESSION. Pour $_POST et $_GET il suffit de vérifier si l'index existe ou non avant de les utiliser. Pour $_SESSION vous devez vous assurer que vous avez commencé la session avec session_start() et que l'index existe aussi.

Notez également que les trois variables sont superglobaux et sont en majuscules.

En relation:


868



Essayez ces

Q1: cet avis signifie que $ varname n'est pas   défini à la portée actuelle de   scénario.

Q2: L'utilisation des conditions isset (), empty () avant d'utiliser une variable suspecte fonctionne 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'];
}

Ou, comme une solution rapide et sale:

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

Note sur les sessions:


109



Une alternative (souvent découragée) est la opérateur de suppression d'erreurs  @. C'est une construction de langage spécifique pour fermer les notifications et les avertissements non désirés, mais doit être utilisé avec précaution.

Tout d'abord, il encourt une pénalité de microperformance sur l'utilisation isset. Ce n'est pas mesurable dans les applications du monde réel, mais devrait être pris en compte dans les itérations lourdes de données. Deuxièmement, cela peut gêner le débogage, mais en même temps, les erreurs supprimées sont en fait transmises aux gestionnaires d'erreurs personnalisés (contrairement aux expressions décorées par isset).


46



Cela signifie que vous testez, évaluez ou imprimez une variable à laquelle vous n'avez encore rien assigné. Cela signifie que vous avez une faute de frappe, ou vous devez vérifier que la variable a été initialisée à quelque chose d'abord. Vérifiez vos chemins logiques, il peut être défini dans un chemin mais pas dans un autre.


35



Généralement en raison de "mauvaise programmation", et une possibilité d'erreurs maintenant ou plus tard.

  1. Si c'est une erreur, faites d'abord une assignation à la variable: $ varname = 0;
  2. Si c'est vraiment défini seulement parfois, testez-le: if (isset($varname))avant de l'utiliser
  3. Si c'est parce que vous avez mal orthographié, corrigez
  4. Peut-être même tourner des avertissements en vous Paramètres PHP

33



Je ne voulais pas désactiver l'avis parce que c'est utile, mais je voulais éviter trop de taper.

Ma solution était cette fonction:

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

Donc, si je veux faire référence à $ name et echo s'il existe, j'écris simplement:

<?=ifexists('name')?>

Pour les éléments de tableau:

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

Dans la page si je veux me référer à $ _REQUEST ['nom']:

<?=ifexistsidx($_REQUEST,'name')?>

30



La meilleure façon d'obtenir des commentaires chaîne est:

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

Ce one-liner est presque équivalent à:

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

Si vous voulez absolument chaîne valeur, juste comme:

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

24



En réponse à "" Pourquoi apparaissent-ils tout d'un coup? J'avais l'habitude d'utiliser ce script pendant des années et je n'ai jamais eu de problème. " 

Il est très commun pour la plupart des sites de fonctionner sous le rapport d'erreur "par défaut" de "Afficher toutes les erreurs, mais pas" avis "et" obsolète "". Ceci sera défini dans php.ini et s'appliquera à tous les sites sur le serveur. Cela signifie que ces "notices" utilisées dans les exemples seront supprimées (cachées) alors que d'autres erreurs, considérées plus critiques, seront montrées / enregistrées.

L'autre paramètre critique est que les erreurs peuvent être masquées (c.-à-d. display_errors mis à "off" ou "syslog").

Qu'est-ce qui s'est passé dans ce cas est que soit le error_reporting a été modifié pour afficher également les notifications (selon les exemples) et / ou que les paramètres ont été modifiés pour display_errors à l'écran (par opposition à les supprimer / les enregistrer).

Pourquoi ont-ils changé?

La réponse évidente / la plus simple est que quelqu'un a ajusté l'un de ces paramètres dans php.ini, ou une version améliorée de PHP utilise maintenant un php.ini différent d'avant. C'est le premier endroit à regarder.

Cependant, il est également possible de remplacer ces paramètres dans

  • .htconf (configuration du serveur web, y compris les vhosts et les sous-configurations) *
  • .htaccess
  • dans le code php lui-même

et n'importe lequel d'entre eux aurait aussi pu être changé.

Il y a aussi la complication supplémentaire que la configuration du serveur web peut activer / désactiver les directives .htaccess, donc si vous avez des directives dans .htaccess qui soudainement commencent / cessent de fonctionner, vous devez vérifier cela.

(.htconf / .htaccess supposez que vous utilisez apache Si vous utilisez une ligne de commande, cela ne s'appliquera pas, si vous exécutez IIS ou un autre serveur web, vous devrez vérifier ces configurations en conséquence)

Résumé

  • Vérifier error_reporting et display_errors Les directives PHP dans php.ini n'ont pas changé, ou que vous n'utilisez pas un php.ini différent d'avant.
  • Vérifier error_reporting et display_errors Les directives php dans .htconf (ou vhosts etc) n'ont pas changé
  • Vérifier error_reporting et display_errors Les directives PHP dans .htaccess n'ont pas changé
  • Si vous avez une directive dans .htaccess, vérifiez si elles sont toujours autorisées dans le fichier .htconf
  • Enfin, vérifiez votre code; peut-être une bibliothèque indépendante; Pour voir si error_reporting et display_errors Les directives PHP ont été définies ici.

24



C'est parce que la variable '$ user_location' n'est pas définie. Si vous utilisez une boucle if à l'intérieur de laquelle vous déclarez la variable '$ user_location', vous devez également avoir une boucle else et définir la même chose. Par exemple:

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

Le code ci-dessus va créer une erreur car la boucle if n'est pas satisfaite et dans la boucle else '$ user_location' n'a pas été défini. Il a toujours été demandé à PHP de répercuter la variable. Donc, pour modifier le code, vous devez effectuer les opérations suivantes:

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

23



la solution rapide consiste à affecter votre variable à null en haut de votre code

$user_location = null;

16