index - variable undefined php




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

Remarque: variable indéfinie

De la vaste sagesse du 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 risque majeur pour la sécurité avec register_globals activé. E_NOTICE erreur de niveau E_NOTICE est émise en cas de travail avec des variables non initialisées, mais pas dans le cas d'ajout d'éléments au tableau non initialisé. isset() construction de langage isset() peut être utilisée pour détecter si une variable a déjà été initialisée. De plus et plus idéal est la solution de empty() car il ne génère pas d'avertissement ou de message d'erreur si la variable n'est pas initialisée.

De la empty() :

Aucun avertissement n'est généré si la variable n'existe pas. Cela signifie que empty () est essentiellement l'équivalent concis de ! 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 elle vérifie la variable par rapport à la suivante, 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 l' éditeur PHP en ligne 3v4l.org

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 faible niveau, E_NOTICE , qui n'est même pas signalée par défaut, mais que le manuel conseille d'autoriser pendant le développement.

Façons de traiter le problème:

  1. Recommandé: Déclarez vos variables, par exemple lorsque vous essayez d'ajouter une chaîne à une variable indéfinie. Ou utilisez isset() / empty() isset() pour vérifier s'ils sont déclarés 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 l' opérateur null coalesce :

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Définissez un gestionnaire d'erreur personnalisé pour E_NOTICE et redirigez les messages de la sortie standard (peut-être vers 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 l' opérateur @ .

Note: 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 list() peut générer ceci quand elle 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, l'index 0 , donc cela va générer:

Avis: Offset non défini: 1

$_GET $_POST / $_GET / $_SESSION

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 la session a démarré avec session_start() et que l'index existe également.

Notez également que les 3 variables sont superglobals . Cela signifie qu'ils doivent être écrits en majuscules.

En relation:

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?

Il s'agit d'une question de référence générale à laquelle les personnes doivent se référer en tant que doublon, au lieu d'avoir à 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:


POURQUOI CELA ARRIVE-T-IL?

Au fil du temps, PHP est devenu un langage plus axé sur la sécurité. Les paramètres qui étaient désactivés par défaut sont maintenant activés par défaut. Un exemple parfait de ceci est E_STRICT , qui est devenu activé par défaut à partir de PHP 5.4.0 .

En outre, selon la documentation PHP, par defualt, E_NOTICE est désactivé dans php.ini. Les documentations PHP recommandent de l'activer à des fins de débogage . Cependant, quand je télécharge PHP depuis le dépôt Ubuntu - et depuis la pile Windows de BitNami - je vois autre chose.

; 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

Notez que error_reporting est défini par défaut sur la valeur de production, et non sur la valeur "default" par défaut. Ceci est quelque peu déroutant et n'est pas documenté en dehors de php.ini, donc je n'ai pas validé cela sur d'autres distributions.

Pour répondre à votre question, cependant, cette erreur apparaît maintenant quand elle ne s'affichait pas avant parce que:

  1. Vous avez installé PHP et les nouveaux paramètres par défaut sont quelque peu mal documentés, mais n'excluent pas E_NOTICE .

  2. E_NOTICE avertissements E_NOTICE tels que les variables non définies et les index indéfinis contribuent en fait à rendre votre code plus propre et plus sûr. Je peux vous dire qu'il y a quelques années, le fait de garder E_NOTICE activé m'a forcé à déclarer mes variables. Cela rend beaucoup plus facile d'apprendre C, où ne pas déclarer les variables est beaucoup plus grand d'une nuisance.

QUE PUIS-JE FAIRE À CE SUJET?

  1. Désactivez E_NOTICE en copiant la "valeur par défaut" E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED et en le remplaçant par ce qui n'est pas commenté après le signe égal à error_reporting = . Redémarrez Apache, ou PHP si vous utilisez CGI ou FPM. Assurez-vous de modifier le "bon" php.ini. La bonne sera Apache si vous utilisez PHP avec Apache, fpm ou php-fpm si vous utilisez PHP-FPM, cgi si vous utilisez PHP-CGI, etc. Ce n'est pas la méthode recommandée, mais si vous avez du code hérité être extrêmement difficile à modifier, alors il pourrait être votre meilleur pari.

  2. Désactivez E_NOTICE au niveau du fichier ou du dossier. Cela peut être préférable si vous avez du code hérité mais que vous voulez faire les choses de la "bonne" façon sinon. Pour ce faire, vous devez consulter Apache2, nginx ou tout autre serveur de votre choix. Dans Apache, vous utiliseriez php_value dans <Directory> .

  3. Réécrivez votre code pour être plus propre. Si vous devez le faire lorsque vous vous déplacez dans un environnement de production, ou que vous ne voulez pas que quelqu'un voit vos erreurs, assurez-vous de désactiver l'affichage des erreurs et de ne log_errors que vos erreurs (voir display_errors et log_errors dans php.ini et votre paramètres du serveur).

Pour développer l'option 3: C'est l'idéal. Si vous pouvez suivre cette route, vous devriez. Si vous n'empruntez pas cette route initialement, envisagez éventuellement de déplacer cette route en testant votre code dans un environnement de développement. Pendant que vous y êtes, débarrassez-vous de ~E_STRICT et ~E_DEPRECATED pour voir ce qui pourrait mal tourner dans le futur. Vous allez voir BEAUCOUP d'erreurs inconnues, mais cela va vous empêcher d'avoir des problèmes désagréables lorsque vous aurez besoin de mettre à niveau PHP dans le futur.

QUE SIGNIFIENT LES ERREURS?

Undefined variable: my_variable_name - Cela se produit lorsqu'une variable n'a pas été définie avant utilisation. Lorsque le script PHP est exécuté, il prend en interne uniquement une valeur nulle. Cependant, dans quel scénario auriez-vous besoin de vérifier une variable avant qu'elle ne soit définie? En fin de compte, c'est un argument pour "code bâclé". En tant que développeur, je peux vous dire que je l'aime quand je vois un projet open source où les variables sont définies comme étant en haut dans leurs champs d'application comme ils peuvent être définis. Il est plus facile de dire quelles variables vont apparaître à l'avenir, et il est plus facile de lire / apprendre le code.

function foo()
{
    $my_variable_name = '';

    //....

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

Undefined index: my_index - Cela se produit lorsque vous essayez d'accéder à une valeur dans un tableau et qu'il n'existe pas. Pour éviter cette erreur, effectuez une vérification conditionnelle.

// 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;   

Une autre option consiste à déclarer un tableau vide en haut de votre fonction. Ce n'est pas toujours possible.

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

//...

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

(conseil supplémentaire)

  • Lorsque je rencontrais ces problèmes et d'autres, j'ai utilisé NetBeans IDE (gratuit) et il m'a donné une foule d'avertissements et d'avis. Certains d'entre eux offrent des conseils très utiles. Ce n'est pas une exigence, et je n'utilise plus d'IDE, sauf pour les grands projets. Je suis plus d'une personne vim ces jours-ci :).

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.


Ces notifications sont my_index fait que la variable utilisée n'est pas defined et my_index clé my_index n'était pas présente dans la variable $my_array .

Ces avis ont été déclenchés à chaque fois, car votre code n'est pas correct, mais vous n'avez probablement pas signalé les notifications.

Résolvez les bugs:

$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 
}

Une autre façon de le sortir:

ini_set("error_reporting", false)

En PHP 7.0, il est maintenant possible d'utiliser l'opérateur de coalescence Null:

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

Est égal à:

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

Manuel PHP PHP 7.0


En ce qui concerne cette partie de la question:

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.

Aucune réponse précise, mais voici quelques explications possibles de la raison pour laquelle les paramètres peuvent «changer» soudainement:

  1. Vous avez mis à jour PHP vers une version plus récente qui peut avoir d'autres valeurs par défaut pour error_reporting, display_errors ou d'autres paramètres pertinents.

  2. Vous avez supprimé ou introduit du code (éventuellement dans une dépendance) qui définit les paramètres pertinents lors de l'exécution à l'aide de ini_set() ou error_reporting() (recherchez-les dans le code)

  3. Vous avez changé la configuration du serveur web (en supposant que c'est apache ici): .htaccess fichiers .htaccess et les configurations vhost peuvent également manipuler les paramètres php.

  4. Habituellement, les avis ne sont pas affichés / rapportés (voir le manuel PHP ), il est donc possible que lors de la configuration du serveur, le fichier php.ini ne puisse pas être chargé pour une raison quelconque (permissions de fichier ??) et vous étiez sur les paramètres par défaut . Plus tard, le 'bug' a été résolu (par accident) et maintenant il peut charger le bon fichier php.ini avec le jeu error_reporting pour afficher les notifications.


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 seulement défini 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 dans vos paramètres PHP

J'avais l'habitude de maudire cette erreur, mais il peut être utile de vous rappeler d'échapper à l'entrée de l'utilisateur.

Par exemple, si vous pensiez que c'était intelligent, code sténographique:

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

... Détrompez-vous! Une meilleure solution est:

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

(J'utilise une fonction html() personnalisée pour échapper les caractères, votre kilométrage peut varier)


Je ne voulais pas désactiver l'avis parce que c'était 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')?>

Le meilleur moyen d'obtenir une chaîne d' entrée 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 une valeur de chaîne , comme:

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

Probablement que vous utilisiez la vieille version de PHP jusqu'à maintenant et mis à jour PHP c'est la raison pour laquelle il fonctionnait sans aucune erreur jusqu'à maintenant des années. jusqu'à PHP4 il n'y avait pas d'erreur si vous utilisez une variable sans la définir mais à partir de PHP5 elle lance des erreurs pour les codes comme mentionné en question.


Probablement que vous utilisiez une ancienne version de PHP


Une alternative (souvent découragée) est l' 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 de 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).


Une autre raison pour laquelle un avis d'index non défini sera généré est qu'une colonne a été omise dans une requête de base de données.

C'est à dire:

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

Ensuite, essayez d'accéder à plus de colonnes / lignes à l'intérieur d'une boucle.

C'est à dire:

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

ou dans une boucle while:

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

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

}

Quelque chose d'autre qui doit être noté est que sur un * NIX OS et Mac OS X, les choses sont sensibles à la casse.

Consultez les questions et réponses suivantes sur Stack:


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

$user_location = null;

pourquoi ne pas garder les choses 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

?>




undefined-index