Frage PHP: "Notice: Undefinierte Variable", "Notice: Undefinierter Index" und "Notice: Undefined Offset"


Ich führe ein PHP-Skript und bekomme immer Fehler wie:

Hinweis: Undefinierte Variable: my_variable_name in C: \ wamp \ www \ mypath \ index.php in Zeile 10

Hinweis: Undefinierter Index: mein_Index C: \ wamp \ www \ mypath \ index.php in Zeile 11

Zeile 10 und 11 sieht so aus:

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

Was bedeuten diese Fehler?

Warum erscheinen sie plötzlich? Ich habe dieses Skript seit Jahren benutzt und ich hatte nie Probleme.

Was muss ich tun, um sie zu beheben?

Dies ist eine allgemeine Referenzfrage für die Leute als doppelt verlinken, anstatt das Problem immer wieder zu erklären. Ich denke, dies ist notwendig, weil die meisten Antworten aus der Praxis zu diesem Thema sehr spezifisch sind.

Verwandte Meta-Diskussion:


948


Ursprung


Antworten:


Hinweis: Undefinierte Variable

Aus der großen Weisheit der PHP Handbuch:

Es ist problematisch, sich auf den Standardwert einer nicht initialisierten Variablen zu verlassen, wenn eine Datei in eine andere eingefügt wird, die denselben Variablennamen verwendet. Es ist auch ein Major Sicherheitsrisiko mit register_globals eingeschaltet. E_NOTIZ Level-Fehler wird ausgegeben, wenn mit nicht initialisierten Variablen gearbeitet wird, jedoch nicht, wenn Elemente an das nicht initialisierte Array angehängt werden. isset () Sprachkonstrukt kann verwendet werden, um festzustellen, ob eine Variable bereits initialisiert wurde. Zusätzlich und ideal ist die Lösung von leer() da es keine Warnung oder Fehlermeldung generiert, wenn die Variable nicht initialisiert wird.

Von PHP-Dokumentation:

Wenn die Variable nicht existiert, wird keine Warnung generiert. Das bedeutet       leer() ist im Wesentlichen das prägnante Äquivalent zu ! isset ($ var) || $ var      == falsch.

Dies bedeutet, dass Sie nur verwenden können empty() um zu bestimmen, ob die Variable gesetzt ist, und zusätzlich prüft sie die Variable gegen folgende, 0,"",null.

Beispiel:

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

Testen Sie das obige Snippet in der 3v4l.org Online-PHP-Editor

Obwohl PHP keine Variablendeklaration erfordert, empfiehlt es es, um einige Sicherheitsschwachstellen oder Fehler zu vermeiden, bei denen man vergessen würde, einer Variablen, die später im Skript verwendet wird, einen Wert zu geben. Was PHP bei nicht deklarierten Variablen tut ist ein sehr niedriger Fehler, E_NOTICEeine, die nicht standardmäßig gemeldet wird, sondern das Handbuch rät zu erlauben während der Entwicklung.

Möglichkeiten, mit dem Problem umzugehen:

  1. Empfohlen: Deklarieren Sie Ihre Variablen, wenn Sie beispielsweise versuchen, eine Zeichenfolge an eine undefinierte Variable anzufügen. Oder benutzen isset() / !empty()  um zu überprüfen, ob sie deklariert sind, bevor sie referenziert werden, wie in:

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

    Dies wurde seit PHP 7.0 viel sauberer, jetzt können Sie das verwenden Nullkoaleszenzoperator:

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Stellen Sie a ein benutzerdefinierter Fehlerhandler für E_NOTICE und leiten die Nachrichten von der Standardausgabe weg (möglicherweise in eine Protokolldatei):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
    
  3. Deaktivieren Sie E_NOTICE von der Berichterstellung. Eine schnelle Möglichkeit, nur auszuschließen E_NOTICE ist:

    error_reporting( error_reporting() & ~E_NOTICE )
    
  4. Unterdrücken Sie den Fehler mit der @ Operator.

Hinweis: Es wird dringend empfohlen, nur Punkt 1 zu implementieren.

Hinweis: Undefinierter Index / Undefinierter Offset

Dieser Hinweis erscheint, wenn Sie (oder PHP) versuchen, auf einen undefinierten Index eines Arrays zuzugreifen.

Möglichkeiten, mit dem Problem umzugehen:

  1. Überprüfen Sie, ob der Index existiert, bevor Sie darauf zugreifen. Dafür können Sie verwenden isset() oder 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. Das Sprachkonstrukt list() kann dies generieren, wenn es versucht, auf einen Array-Index zuzugreifen, der nicht existiert:

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

Zwei Variablen werden verwendet, um auf zwei Array-Elemente zuzugreifen, jedoch gibt es nur ein Array-Element, den Index 0, so wird dies erzeugen:

Hinweis: Undefinierter Offset: 1

$_POST / $_GET / $_SESSION Variable

Die obigen Hinweise erscheinen oft beim Arbeiten mit $_POST, $_GET oder $_SESSION. Zum $_POST und $_GET Sie müssen nur überprüfen, ob der Index vorhanden ist oder nicht, bevor Sie sie verwenden. Zum $_SESSION Sie müssen sicherstellen, dass Sie mit der Sitzung begonnen haben session_start() und dass der Index auch existiert.

Beachten Sie auch, dass alle 3 Variablen sind Superglobale und sind Großbuchstaben.

Verbunden:


868



Probiere diese

Q1: Diese Nachricht bedeutet $ Varname ist nicht   definiert im aktuellen Umfang der   Skript.

F2: Die Verwendung der Bedingungen isset () und empty () vor der Verwendung verdächtiger Variablen funktioniert gut.

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

Oder als schnelle und schmutzige Lösung:

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

Hinweis zu Sitzungen:


109



Eine (oft entmutigte) Alternative ist die Fehlerunterdrückungsoperator  @. Es ist ein spezielles Sprachkonstrukt, um unerwünschte Hinweise und Warnungen zu beenden, sollte aber vorsichtig verwendet werden.

Erstens verursacht es eine Mikroperformance-Strafe gegenüber der Verwendung isset. Das ist in realen Anwendungen nicht messbar, sollte aber in datenintensiven Iterationen berücksichtigt werden. Zweitens könnte es das Debugging behindern, aber gleichzeitig werden unterdrückte Fehler tatsächlich an benutzerdefinierte Fehlerbehandlungsroutinen übergeben (im Gegensatz zu mit Isset dekorierten Ausdrücken).


46



Das bedeutet, dass Sie eine Variable testen, auswerten oder drucken, der Sie noch keine zugewiesen haben. Es bedeutet, dass Sie entweder einen Tippfehler haben, oder Sie müssen überprüfen, ob die Variable zuerst initialisiert wurde. Überprüfen Sie Ihre logischen Pfade, es kann in einem Pfad festgelegt werden, aber nicht in einem anderen.


35



Im Allgemeinen wegen "schlechter Programmierung" und einer Möglichkeit für Fehler jetzt oder später.

  1. Wenn es ein Fehler ist, machen Sie der Variablen zuerst eine korrekte Zuweisung: $ varname = 0;
  2. Wenn es wirklich nur manchmal definiert ist, teste dafür: if (isset($varname)), bevor Sie es verwenden
  3. Wenn du es falsch buchstabiert hast, korrigiere es einfach
  4. Vielleicht sogar die Warnungen in dir drehen PHP-Einstellungen

33



Ich wollte die Benachrichtigung nicht deaktivieren, weil sie hilfreich ist, aber ich wollte zu viel tippen vermeiden.

Meine Lösung war diese Funktion:

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

Wenn ich also auf $ name und echo referenzieren möchte, schreibe ich einfach:

<?=ifexists('name')?>

Für Array-Elemente:

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

Auf der Seite, wenn ich auf $ _REQUEST ['name'] verweisen möchte:

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

30



Der beste Weg, um Input zu erhalten Zeichenfolge ist:

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

Dieser One-Liner ist fast gleichwertig mit:

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

Wenn du unbedingt willst Zeichenfolge Wert, genau wie:

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

24



Als Antwort auf "" Warum erscheinen sie plötzlich? Ich habe dieses Skript seit Jahren benutzt und ich hatte nie ein Problem. " 

Es ist sehr üblich, dass die meisten Websites unter der Standardfehlerberichterstattung von "Alle Fehler anzeigen, aber nicht" Benachrichtigungen "und" Abgelehnt "" ausgeführt werden. Dies wird in php.ini festgelegt und auf alle Sites auf dem Server angewendet. Dies bedeutet, dass diese "Hinweise", die in den Beispielen verwendet werden, unterdrückt (versteckt) werden, während andere Fehler, die als kritischer angesehen werden, gezeigt / aufgezeichnet werden.

Die andere kritische Einstellung ist, dass die Fehler verborgen sein können (d. H. display_errors auf "Aus" oder "Syslog" gesetzt).

Was in diesem Fall passiert ist, ist, dass entweder die error_reporting wurde geändert, um auch Hinweise (gemäß Beispielen) anzuzeigen und / oder dass die Einstellungen geändert wurden display_errors auf dem Bildschirm (im Gegensatz zur Unterdrückung / Protokollierung).

Warum haben sie sich verändert?

Die offensichtliche / einfachste Antwort ist, dass jemand eine dieser Einstellungen in php.ini angepasst hat, oder eine verbesserte Version von PHP verwendet nun eine andere php.ini von vorher. Das ist der erste Ort, um zu schauen.

Es ist jedoch auch möglich, diese Einstellungen in zu überschreiben

  • .htconf (Webserver-Konfiguration, einschließlich vhosts und Sub-Konfigurationen) *
  • .htaccess
  • im PHP-Code selbst

und jede von diesen könnte auch geändert worden sein.

Es gibt auch die zusätzliche Komplikation, dass die Webserver-Konfiguration .htaccess-Direktiven aktivieren / deaktivieren kann. Wenn Sie Anweisungen in .htaccess haben, die plötzlich anfangen zu arbeiten, dann müssen Sie dies überprüfen.

(.htconf / .htaccess setzt voraus, dass Sie als Apache ausgeführt werden. Wenn Sie eine Befehlszeile ausführen, gilt dies nicht; wenn Sie IIS oder einen anderen Webserver ausführen, müssen Sie diese Einstellungen entsprechend überprüfen.)

Zusammenfassung

  • Prüfen error_reporting und display_errors php directions in php.ini hat sich nicht geändert, oder Sie verwenden keine andere php.ini von vorher.
  • Prüfen error_reporting und display_errors php-Anweisungen in .htconf (oder vhosts usw.) haben sich nicht geändert
  • Prüfen error_reporting und display_errors php-Anweisungen in .htaccess wurden nicht geändert
  • Wenn Sie eine Direktive in .htaccess haben, überprüfen Sie, ob sie in der .htconf-Datei noch erlaubt sind
  • Überprüfen Sie abschließend Ihren Code. möglicherweise eine nicht verwandte Bibliothek; zu sehen, wenn error_reporting und display_errors php-Direktiven wurden dort eingestellt.

24