"Remarque: variable non définie", "Remarque: index non défini" et "Remarque: décalage non défini" à l'aide de PHP

1174

J'exécute un script PHP et continue de recevoir des erreurs comme:

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

Remarque: index non défini: mon_index C: \ wamp \ www \ mypath \ index.php sur 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"];

Quelle est la signification de ces messages d'erreur?

Pourquoi apparaissent-ils tout d'un coup? J'utilisais ce script depuis des années et je n'ai jamais eu de problème.

Comment les réparer?


Il s'agit d'une question de référence générale à laquelle les personnes doivent se connecter en tant que doublon, au lieu d'avoir à expliquer le problème à maintes reprises. Je pense que cela est nécessaire car la plupart des réponses du monde réel sur cette question sont très spécifiques.

Meta discussion connexe:

Pekka 웃
la source
3
la variable n'a peut-être pas été initialisée. Êtes-vous en train d'initialiser la variable à partir d'un article ou d'un get ou d'un tableau? Si tel est le cas, vous pourriez ne pas avoir de champ dans ce tableau. C'est votre accès.
Anish Silwal
3
@Pekka 웃 - J'ai remarqué la modification en ajoutant "et" Remarque: décalage non défini "" - Ne serait-il pas plus logique d'utiliser "PHP:" Variable non définie "," Index non défini "," Décalage non défini "" le PHP, car il est étiqueté comme "php". De plus, l'URL est coupée à and-notice-undef, juste une suggestion pour que l'URL ne soit pas coupée. Peut-être même en supprimant les (trop) citations. OuPHP: “Undefined variable/index/offset” notices
Funk Forty Niner
2
@Fred Je suppose qu'un argument peut être avancé pour les deux variantes. Il y a une chance que les débutants entrent dans toute la ligne, y compris le "Remarque:" dans leur requête de recherche, qui, je suis sûr, est le principal générateur de trafic pour cette question. Si les messages sont là dans leur intégralité, cela améliorera probablement la visibilité dans les moteurs de recherche
Pekka
2
@Pekka 웃 Je comprends. Je l'ai seulement dit parce que l'URL n'avait pas été coupée avant et maintenant c'est le cas and-notice-undef. Ce n'était qu'une (quelques) suggestion (s). Il se répète simplement aussi Notice: Undefined.
Funk Forty Niner du

Réponses:

1066

Remarque: variable non définie

De la grande sagesse du manuel PHP :

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

De la documentation PHP :

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 pouvez utiliser uniquement empty()pour déterminer si la variable est définie, et en outre , il vérifie la variable par rapport à ce qui suit, 0, 0.0, "", "0", null, falseou [].

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 vulnérabilités de sécurité ou bogues où l'on oublierait de donner une valeur à une variable qui sera utilisée plus tard dans le script. Dans le cas des variables non déclarées, PHP émet une erreur de très bas niveau, E_NOTICEqui n'est même pas signalée par défaut, mais le manuel conseille de l'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 non définie. Ou utilisez isset()/ !empty() 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'] : '';
    

    Cela 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'erreurs personnalisé pour E_NOTICE et redirigez les messages loin de la sortie standard (peut-être vers un fichier journal):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
  3. Désactivez E_NOTICE de la création de rapports. Un moyen rapide d'exclure E_NOTICEest simplement :

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

Remarque: il est fortement recommandé de n'implémenter que le point 1.

Remarque: index non défini / décalage non défini

Cette notification apparaît lorsque vous (ou PHP) essayez d'accéder à un index non dé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 du langage list()peut générer cela lorsqu'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, index 0, donc cela générera:

Remarque: décalage indéfini: 1

$_POST/ $_GET/ $_SESSIONvariable

Les avis apparaissent au- dessus souvent lorsque vous travaillez avec $_POST, $_GETou $_SESSION. Pour $_POSTet il $_GETvous suffit de vérifier si l'index existe ou non avant de les utiliser. Car $_SESSIONvous devez vous assurer d'avoir démarré la session session_start()et que l'index existe également.

Notez également que les 3 variables sont superglobales et sont en majuscules.

En relation:

Rizier123
la source
7
@ dieselpower44 Quelques réflexions: "L'opérateur de fermeture" ( @) a quelques problèmes de performances. De plus, comme il supprime toutes les erreurs dans une portée particulière, son utilisation sans précaution peut masquer les messages que vous souhaiteriez voir.
IMSoP du
6
Cacher les problèmes n'est PAS la façon de traiter les problèmes. Les éléments # 2 ... # 4 ne peuvent être utilisés que sur des serveurs de production, pas en général.
Salman A
1
Est-il possible de fermer le message en ligne (pas dans le gestionnaire) lorsqu'un gestionnaire d'erreur personnalisé est également utilisé? $var = @$_GET['nonexisting'];cause toujours un avis ..
Alph.Dev
18
Pourquoi est-il recommandé d'utiliser 1. $value = isset($_POST['value']) ? $_POST['value'] : '';au lieu d'utiliser 4. $value = @$_POST['value'];?
forsvunnet
@twistedpixel Ces 4 façons sont indépendantes, ce n'est pas un guide en 4 étapes. Donc, si vous avez choisi d'utiliser la méthode 4, cela signifie que vous n'avez pas implémenté les 3 premières méthodes, vous n'avez donc pas encore supprimé les erreurs.
Aycan Yaşıt
141

Essayez-les

Q1: cet avis signifie que $ varname n'est pas défini dans la portée actuelle du script.

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

Remarque sur les sessions:

Ish
la source
Si vous utilisez à E_NOTICEpartir du php.inifichier de configuration, faiteserror_reporting = (E_ALL & ~E_NOTICE)
ahmd0
De la réponse ci-dessus, j'ai essayé isset, array_key_exists mais cela n'a pas fonctionné. J'ai essayé votre réponse, .empty (), et cela fonctionne. Merci beaucoup!
ewef
63

Opérateur d' affichage d'erreur@

Pour les notifications indésirables et redondantes, on pourrait utiliser l' @opérateur dédié pour » masquer « les messages variables / index non définis.

$var = @($_GET["optional_param"]);
  • Ceci est généralement découragé. Les nouveaux arrivants ont tendance à en abuser.
  • C'est très inapproprié pour le code au plus profond de la logique d'application (en ignorant les variables non déclarées là où vous ne devriez pas), par exemple pour les paramètres de fonction, ou en boucles.
  • Il y a une tête sur le isset?:ou ??super-supression cependant. Les notifications peuvent toujours être enregistrées. Et on peut ressusciter des @notifications cachées avec:set_error_handler("var_dump");
    • De plus, vous ne devriez pas utiliser / recommander habituellement if (isset($_POST["shubmit"]))dans votre code initial.
    • Les nouveaux arrivants ne repéreront pas de telles fautes de frappe. Cela vous prive simplement des avis PHP pour ces cas-là. Ajoutez @ou issetseulement après avoir vérifié la fonctionnalité.
    • Corrigez d'abord la cause. Pas les avis.

  • @est principalement acceptable pour les paramètres $_GET/ $_POSTinput, en particulier s'ils sont facultatifs .

Et puisque cela couvre la majorité de ces questions, développons les causes les plus courantes:

$_GET/ $_POST/ $_REQUESTentrée non définie

  • La première chose que vous faites lorsque vous rencontrez un index / décalage indéfini, est de vérifier les fautes de frappe:
    $count = $_GET["whatnow?"];

    • S'agit-il d'un nom de clé attendu et présent sur chaque demande de page?
    • Les noms de variable et les indices de tableau sont sensibles à la casse en PHP.
  • Deuxièmement, si l'avis n'a pas de cause évidente, utilisez var_dumpou print_rpour vérifier tous les tableaux d'entrée pour leur contenu actuel:

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

    Les deux indiqueront si votre script a été invoqué avec le bon ou n'importe quel paramètre.

  • Alternativement ou utilisez en plus votre navigateur devtools ( F12) et inspectez l'onglet réseau pour les requêtes et les paramètres:

    outils de développement du navigateur / onglet réseau

    Les paramètres POST et l'entrée GET seront affichés séparément.

  • Pour les $_GETparamètres , vous pouvez également le coup d' oeil à QUERY_STRINGen

    print_r($_SERVER);

    PHP a quelques règles pour fusionner les noms de paramètres non standard dans les superglobaux. Apache pourrait également effectuer une réécriture. Vous pouvez également consulter les en- $_COOKIEStêtes de requête HTTP bruts et autres fournis de cette façon.

  • Plus évidemment, regardez la barre d'adresse de votre navigateur pour les paramètres GET :

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

    Les name=valuepaires après le point d' ?interrogation sont vos paramètres de requête (GET). Ainsi, cette URL ne pouvait que produire $_GET["id"]et $_GET["sort"].

  • Enfin, vérifiez vos déclarations <form>et<input> , si vous attendez un paramètre mais n'en recevez aucun.

    • Assurez-vous que chaque entrée requise possède un <input name=FOO>
    • L' attribut id=ou title=ne suffit pas.
    • Un method=POSTformulaire doit remplir $_POST.
    • Alors qu'un method=GET(ou le laisser de côté) produirait des $_GETvariables.
    • Il est également possible qu'un formulaire soit fourni action=script.php?get=paramvia $ _GET et les method=POSTchamps restants de $ _POST à ​​côté.
    • Avec les configurations PHP modernes (≥ 5.6), il est devenu possible (non à la mode) de réutiliser $_REQUEST['vars'], ce qui écrase les paramètres GET et POST.
  • Si vous utilisez mod_rewrite, vous devez vérifier les deux access.logainsi que permettre à la RewriteLogde comprendre les paramètres absents.

$_FILES

  • Les mêmes contrôles d'intégrité s'appliquent aux téléchargements de fichiers et $_FILES["formname"].
  • De plus, vérifiez enctype=multipart/form-data
  • Ainsi que method=POSTdans votre <form>déclaration.
  • Voir aussi: Erreur d'index PHP non défini $ _FILES?

$_COOKIE

  • Le $_COOKIEtableau n'est jamais rempli juste après setcookie(), mais uniquement sur toute demande HTTP de suivi.
  • De plus, leur validité expire, ils peuvent être une contrainte pour les sous-domaines ou les chemins individuels, et l'utilisateur et le navigateur peuvent simplement les rejeter ou les supprimer.
mario
la source
2
Si vous êtes curieux de savoir quel est l'impact sur les performances, cet article le résume bien, derickrethans.nl/… .
Gajus
@GajusKuizinas Il y a eu quelques changements depuis 2009, en particulier php.net/ChangeLog-5.php#5.4.0 change radicalement le résultat (voir "Zend Engine, performance" et "(silence) operator").
mario
Merci @mario, intéressant. Maintenant, si quelqu'un était assez bon pour comparer les deux ... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs Selon ce test, semblent identiques (notez que les changements d'échelle).
Gajus le
47

Généralement à cause d'une "mauvaise programmation" et d'une possibilité d'erreurs maintenant ou plus tard.

  1. Si c'est une erreur, faites d'abord une affectation correcte à la variable: $ varname = 0;
  2. S'il n'est vraiment défini que parfois, testez-le:, if (isset($varname))avant de l'utiliser
  3. Si c'est parce que vous l'avez mal orthographié, corrigez simplement
  4. Peut-être même désactiver les avertissements dans vos paramètres PHP
Erik
la source
5
Veuillez ne pas désactiver les avertissements. Dans les langages plus stricts, ils signifient souvent "il pourrait y avoir un bogue, vous feriez mieux de vérifier cette ligne deux fois" - dans un langage aussi permissif que PHP, ils signifient souvent "ce code est merdique et proprement criblé de bogues; je vais essayer de faire un peu de sens mais vous feriez mieux de résoudre ce problème dès que possible ".
5
Bien que je sois d'accord avec les trois premiers points, # 4 est tout simplement faux. Cacher un problème ne le fera pas disparaître, et cela pourrait même causer plus de problèmes en cours de route.
Valentin Flachsel
1
@Freek absolument vrai, mais dans certains scénarios (script acheté, aucune connaissance technique, besoin de le faire fonctionner demain ...), c'est la solution de ruban adhésif - vraiment mauvaise, qui doit toujours être soulignée, mais une option
Pekka
Le ruban adhésif est bon ... parfois. Historiquement, les avertissements ont été désactivés dans les paramètres PHP standard, mais les paramètres par défaut sont devenus plus stricts. Dommage que beaucoup reviennent aux anciens paramètres, pour ne pas déranger les clients.
Erik
41

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

DGM
la source
34

Je ne voulais pas désactiver l'avis car c'est utile, mais je voulais éviter de trop 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 du tableau:

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

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

<?=ifexistsidx($_REQUEST,'name')?>
Ferenci Zoltán László
la source
2
Votre fonction ifexists () ne fonctionne pas pour moi en PHP 5.3. Les variables de l'appelant ne sont pas disponibles dans la portée locale de la fonction (voir Portée variable ), à moins qu'il ne s'agisse de Superglobals ou que vous ne jouiez avec $ GLOBALS , donc $foo = "BABAR"; ifexists('foo');retourneront en général null. (Les italiques sont les chapitres de php.net.)
skierpage
maintenant vous obtiendrez "bonjour de" ... quel est le point? il suffit de vérifier la valeurif( !empty($user) and !empty($location) ) echo "hello $user ..."
gcb
27

La meilleure façon d'obtenir une chaîne d' entrée est:

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

Cette doublure équivaut presque à:

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 , tout comme:

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

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 la définir. Par exemple:

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

Le code ci-dessus créera une erreur car la boucle if n'est pas satisfaite et dans la boucle else '$ user_location' n'a pas été défini. PHP a quand même été invité à faire écho à la variable. Donc, pour modifier le code, vous devez faire ce qui suit:

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

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

Il est très courant que la plupart des sites fonctionnent sous le rapport d'erreurs "par défaut" de "Afficher toutes les erreurs, mais pas les" notifications "et les" obsolètes "". Cela sera défini dans php.ini et s'appliquera à tous les sites sur le serveur. Cela signifie que ces "notifications" utilisées dans les exemples seront supprimées (masquées) tandis que d'autres erreurs, considérées comme plus critiques, seront affichées / enregistrées.

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

Ce qui se sera produit dans ce cas, c'est que le a error_reportingété modifié pour afficher également les avis (selon les exemples) et / ou que les paramètres ont été modifiés à l' display_errorsécran (par opposition à les supprimer / à les enregistrer).

Pourquoi ont-ils changé?

La réponse la plus évidente / la plus simple est que quelqu'un a ajusté l'un de ces paramètres dans php.ini, ou une version mise à niveau 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 hôtes virtuels et les sous-configurations) *
  • .htaccess
  • dans le code php lui-même

et n'importe lequel d'entre eux aurait également pu être modifié.

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 démarrent / s'arrêtent soudainement, vous devez vérifier cela.

(.htconf / .htaccess suppose que vous exécutez en tant qu'apache. Si vous exécutez la 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)

Sommaire

  • Les directives de vérification error_reportinget display_errorsphp dans php.ini n'ont pas changé, ou que vous n'utilisez pas un php.ini différent d'avant.
  • Les directives de vérification error_reportinget display_errorsphp dans .htconf (ou vhosts, etc.) n'ont pas changé
  • Les directives de vérification error_reportinget display_errorsphp 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; éventuellement une bibliothèque indépendante; pour voir si les directives php error_reportinget y display_errorsont été définies.
Robbie
la source
20

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

$user_location = null;
Shahin Mammadzada
la source
16

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 un code abrégé intelligent:

// 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 html()fonction personnalisée pour échapper aux personnages, votre kilométrage peut varier)

rybo111
la source
15

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

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

Égale à:

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

Manuel PHP PHP 7.0

elpiel
la source
Cela fonctionne également très bien dans les instructions if. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
un codeur
Votre code est en fait un joli bug négligé: ?? - ne vérifie que isset()si vous réussissez is_array()- ce qui est un comportement booléen et inattendu.
elpiel
14

J'utilise toujours la fonction utile exst () qui déclare automatiquement les variables.

Votre code sera -

$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;
}
utilisateur2253362
la source
14

Dans un langage très simple .
L'erreur est que vous utilisez une variable $user_locationque vous n'avez pas définie précédemment et qui n'a aucune valeur. Je vous recommande donc de déclarer cette variable avant de l' utiliser , par exemple:


$user_location = '';
Ou
$user_location = 'Los Angles';
Il s'agit d'une erreur très courante à laquelle vous pouvez faire face, alors ne vous inquiétez pas, déclarez simplement la variable et profitez du codage .

Rishabh Seth
la source
8

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

?>
gts
la source
8

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 auparavant désactivés par défaut sont désormais activés par défaut. Un exemple parfait de cela est E_STRICT, qui est devenu activé par défaut à partir de PHP 5.4.0 .

De plus, selon la documentation PHP, par défaut, E_NOTICEest désactivé dans php.ini. Les documents PHP recommandent de l'activer à des fins de débogage . Cependant, lorsque je télécharge PHP depuis le référentiel 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_reportingla valeur de production est en fait définie par défaut, et non la valeur "par défaut" 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 alors qu'elle ne s'est pas produite auparavant parce que:

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

  2. E_NOTICEdes avertissements tels que des variables non définies et des index non définis contribuent à rendre votre code plus propre et plus sûr. Je peux vous dire que, il y a des années, garder E_NOTICEactivé m'a forcé à déclarer mes variables. Cela rendait beaucoup plus facile l'apprentissage du C, ne déclarait pas que les variables étaient beaucoup plus importantes.

QUE PUIS-JE FAIRE À CE SUJET?

  1. Désactivez-le E_NOTICEen copiant la «valeur par défaut» E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATEDet en la remplaçant par ce qui n'est actuellement pas commenté après la connexion égale error_reporting =. Redémarrez Apache ou PHP si vous utilisez CGI ou FPM. Assurez-vous que vous éditez le "bon" php.ini. Le bon sera Apache si vous exécutez PHP avec Apache, fpm ou php-fpm si vous exécutez PHP-FPM, cgi si vous exécutez PHP-CGI, etc. Ce n'est pas la méthode recommandée, mais si vous avez du code hérité qui va être extrêmement difficile à modifier, alors ce pourrait être votre meilleur pari.

  2. Désactivez au niveau E_NOTICEdu 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 manière sinon. Pour ce faire, vous devez consulter Apache2, Nginx ou quel que soit le serveur de votre choix. Dans Apache, vous utiliseriez l' php_valueintérieur de <Directory>.

  3. Réécrivez votre code pour être plus propre. Si vous devez le faire lors du passage à un environnement de production ou si vous ne voulez pas que quelqu'un voit vos erreurs, assurez-vous de désactiver l'affichage des erreurs et de ne consigner que vos erreurs (voir display_errorset log_errorsdans php.ini et les paramètres de votre serveur) .

Pour développer l'option 3: c'est l'idéal. Si vous pouvez suivre cette voie, vous devriez. Si vous ne suivez pas cette route initialement, envisagez de la déplacer éventuellement en testant votre code dans un environnement de développement. Pendant que vous y êtes, débarrassez-vous ~E_STRICTet ~E_DEPRECATEDvoyez ce qui pourrait mal se passer à l'avenir. Vous allez voir BEAUCOUP d'erreurs inconnues, mais cela vous empêchera d'avoir des problèmes désagréables lorsque vous aurez besoin de mettre à niveau PHP à l'avenir.

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 simplement en interne 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 le "code bâclé". En tant que développeur, je peux vous dire que j'adore ça quand je vois un projet open source où les variables sont définies aussi haut dans leur portée qu'elles peuvent l'être. Il permet de savoir plus facilement quelles variables vont apparaître à l'avenir et facilite la lecture / l'apprentissage du 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'elle 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 cela m'a donné une multitude d'avertissements et de notifications. 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 une vimpersonne de nos jours :).
smcjones
la source
6

index non défini signifie dans un tableau que vous avez demandé pour un index de tableau non disponible, par exemple

<?php 

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

?>

variable non définie signifie que vous avez utilisé une variable complètement inexistante ou qui n'est pas définie ou initialisée par ce nom par exemple

<?php print_r($myvar); ?>

décalage indéfini signifie dans le tableau que vous avez demandé une clé non existante. Et la solution pour cela est de vérifier avant utilisation

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

Concernant cette partie de la question:

Pourquoi apparaissent-ils tout d'un coup? J'utilisais ce script depuis des années et je n'ai jamais eu de problème.

Aucune réponse définitive, mais voici quelques explications possibles des raisons pour lesquelles les paramètres peuvent changer «soudainement»:

  1. Vous avez mis à niveau 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 qu'Apache ici): les .htaccessfichiers et les configurations vhost peuvent également manipuler les paramètres php.

  4. Habituellement, les notifications ne s'affichent / ne sont pas signalées (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 (autorisations 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 fichier php.ini correct avec le jeu error_reporting pour afficher les notifications.

Wouter de Winter
la source
3

Si vous travaillez avec des classes, vous devez vous assurer de référencer les variables membres en utilisant $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
la source
3

Une autre raison pour laquelle un avis d'index non défini sera levé serait qu'une colonne a été omise d'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 dans une boucle.

C'est à dire:

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

ou en whileboucle:

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

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

}

Il faut également noter que sur un * NIX OS et Mac OS X, les choses sont sensibles à la casse.

Consultez les questions et réponses suivantes sur Stack:

Fred -ii-
la source
3

L'utilisation d'un ternaire est simple, lisible et propre:

Pré PHP 7
Attribuez une variable à la valeur d'une autre variable si elle est définie, sinon affecteznull(ou quelle que soit lavaleur par défaut dont vous avez besoin):

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

PHP 7+ Identique
sauf en utilisant Null Coalescing Operator . Il n'est plus nécessaire d'appeler isset()car cela est intégré, et pas besoin de fournir la variable à renvoyer car elle est supposée renvoyer la valeur de la variable vérifiée:

$newVariable = $thePotentialData ?? null;

Les deux arrêteront les avis de la question OP, et les deux sont l'équivalent exact de:

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

 
Si vous n'avez pas besoin de définir une nouvelle variable, vous pouvez directement utiliser la valeur retournée du ternaire, comme avec echo, les arguments de fonction, etc.:

Écho:

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

Une fonction:

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

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

Ce qui précède fonctionnera de la même manière avec les tableaux, y compris les sessions, etc., en remplaçant la variable en cours de vérification par exemple:
$_SESSION['checkMe']
ou quel que soit le niveau de profondeur dont vous avez besoin, par exemple:
$clients['personal']['address']['postcode']


 

Suppression:

Il est possible de supprimer les avis PHP avec @ou de réduire votre niveau de rapport d'erreurs, mais cela ne résout pas le problème , il arrête simplement qu'il soit signalé dans le journal des erreurs. Cela signifie que votre code a toujours essayé d'utiliser une variable qui n'a pas été définie, ce qui peut ou non signifier que quelque chose ne fonctionne pas comme prévu - selon l'importance de la valeur manquante.

Vous devriez vraiment vérifier ce problème et le traiter de manière appropriée, soit en servant un message différent, soit en renvoyant simplement une valeur nulle pour tout le reste afin d'identifier l'état précis.

Si vous vous souciez simplement que l'avis ne figure pas dans le journal des erreurs, vous pouvez simplement ignorer le journal des erreurs en option.

James
la source
1

Une cause courante d'une variable qui n'existe pas après la soumission d' un formulaire HTML est que l'élément de formulaire n'est pas contenu dans une <form>balise:

Exemple: élément non contenu dans le <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>

Exemple: élément maintenant contenu dans le <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
la source
0

Vous utilisiez probablement l'ancienne version de PHP jusqu'à maintenant et vous avez mis à jour PHP, c'est la raison pour laquelle il fonctionnait sans erreur jusqu'à maintenant depuis 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 génère des erreurs pour les codes comme mentionné en question.

phvish
la source
0

Lorsque vous traitez des fichiers, un enctype et une méthode POST appropriés sont requis, ce qui déclenchera un avis d'index non défini si l'un ou l'autre n'est pas inclus dans le formulaire.

Le manuel indique la syntaxe de base suivante:

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

?>

Référence:

Funk Forty Niner
la source
0

J'ai posé une question à ce sujet et j'ai été renvoyé à ce message avec le message:

Cette question a déjà une réponse ici:

"Remarque: variable non définie", "Remarque: index non défini" et "Remarque: décalage non défini" à l'aide de PHP

Je partage ici ma question et ma solution:

Voici l'erreur:

entrez la description de l'image ici

La ligne 154 est le problème. Voici ce que j'ai à la ligne 154:

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

Je pense que le problème est que j'écris des conditions pour la variable $city, qui n'est pas la clé mais la valeur $key => $city. Tout d'abord, pourriez-vous confirmer si c'est la cause de l'avertissement? Deuxièmement, si tel est le problème, pourquoi ne puis-je pas écrire une condition basée sur la valeur? Doit-il être avec la clé dont j'ai besoin pour écrire la condition?

MISE À JOUR 1: Le problème est que lors de l'exécution $citiesCounterArray[$key], parfois $keycorrespond à une clé qui n'existe pas dans le $citiesCounterArraytableau, mais ce n'est pas toujours le cas en fonction des données de ma boucle. Ce dont j'ai besoin, c'est de définir une condition pour que s'il $keyexiste dans le tableau, puis d'exécuter le code, sinon, sautez-le.

MISE À JOUR 2: Voici comment je l'ai corrigé en utilisant array_key_exists():

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

Ces erreurs se produisent chaque fois que nous utilisons une variable qui n'est pas définie.

La meilleure façon de les gérer est de définir des rapports d'erreurs pendant le développement.

Pour définir le rapport d'erreurs sur:

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

Sur les serveurs de production, le rapport d'erreurs est désactivé, par conséquent, nous n'obtenons pas ces erreurs.

Sur le serveur de développement, cependant, nous pouvons définir le rapport d'erreurs.

Pour se débarrasser de cette erreur, nous voyons l'exemple suivant:

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

Nous pouvons initialiser les variables à NULLavant d'attribuer leurs valeurs ou de les utiliser.

Ainsi, nous pouvons modifier le code comme:

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

Cela ne perturbera aucune logique de programme et ne produira pas d'avis même s'il $testn'a pas de valeur.

Donc, en gros, il est toujours préférable d'activer le rapport d'erreurs pour le développement.

Et corrigez toutes les erreurs.

Et en production, le rapport d'erreurs doit être désactivé.

élève
la source
-1

Ces avis sont dus au fait que vous n'avez pas la variable utilisée definedet que la my_indexclé n'était pas présente dans la $my_arrayvariable.

Ces notifications ont été déclenchées à chaque fois, car la vôtre coden'est pas correcte, mais vous n'aviez 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 sortir ça:

ini_set("error_reporting", false)
Andrei Todorut
la source
-2

En PHP, vous devez d'abord définir la variable pour pouvoir l'utiliser.
On peut vérifier que la variable est définie ou pas de manière très efficace!.

//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)){

}

Explication 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";
}
Manish Goswami
la source