"Hinweis: Undefinierte Variable", "Hinweis: Undefinierter Index" und "Hinweis: Undefinierter Offset" mit PHP

1173

Ich führe ein PHP-Skript aus und erhalte weiterhin Fehler wie:

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

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

Zeile 10 und 11 sehen folgendermaßen aus:

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

Was bedeuten diese Fehlermeldungen?

Warum tauchen sie plötzlich auf? Ich habe dieses Skript jahrelang benutzt und hatte nie ein Problem.

Wie behebe ich sie?


Dies ist eine allgemeine Referenzfrage, auf die Personen als Duplikat verlinken können, anstatt das Problem immer wieder erklären zu müssen. Ich halte dies für notwendig, da die meisten realen Antworten zu diesem Thema sehr spezifisch sind.

Verwandte Meta-Diskussion:

Pekka 웃
quelle
8
Mögliches Duplikat der Referenz - Was bedeutet dieser Fehler in PHP?
Meagar
3
Die Variable wurde möglicherweise nicht initialisiert. Initialisieren Sie die Variable aus einem Post oder Get oder einem Array? In diesem Fall befindet sich möglicherweise kein Feld in diesem Array. Dass Sie darauf zugreifen.
Anish Silwal
3
@Pekka 웃 - Ich habe die Bearbeitung beim Hinzufügen von "und" bemerkt. Hinweis: Undefinierter Versatz "- Wäre es nicht sinnvoller," PHP: "Undefinierte Variable", "Undefinierter Index", "Undefinierter Versatz" zu verwenden? aus dem PHP, da es als "php" markiert ist. Außerdem wird die URL abgeschnitten and-notice-undef, nur ein Vorschlag, damit die URL nicht abgeschnitten wird. Vielleicht sogar die (zu vielen) Anführungszeichen entfernen. OderPHP: “Undefined variable/index/offset” notices
Funk Forty Niner
2
@Fred Ich denke, für beide Varianten kann ein Argument vorgebracht werden. Es besteht die Möglichkeit, dass Neulinge die gesamte Zeile einschließlich des "Hinweises" in ihre Suchabfrage eingeben. Ich bin sicher, dass dies der Hauptverkehrsgenerator für diese Frage ist. Wenn die Nachrichten vollständig vorhanden sind, wird dies wahrscheinlich die Sichtbarkeit in Suchmaschinen verbessern
Pekka
2
@ Pekka 웃 Ich verstehe. Ich habe das nur gesagt, weil die URL vorher nicht abgeschnitten wurde und jetzt bei and-notice-undef. Es war nur ein (wenige) Vorschlag (e). Es wiederholt sich einfach auch sein Notice: Undefined.
Funk Forty Niner

Antworten:

1066

Hinweis: Undefinierte Variable

Aus der großen Weisheit des PHP-Handbuchs :

Das Verlassen auf den Standardwert einer nicht initialisierten Variablen ist problematisch, wenn eine Datei in eine andere aufgenommen wird, die denselben Variablennamen verwendet. Es ist auch ein großes Sicherheitsrisiko mit register_globals eingeschaltet. Der Fehler auf E_NOTICE- Ebene wird ausgegeben, wenn mit nicht initialisierten Variablen gearbeitet wird, jedoch nicht, wenn Elemente an das nicht initialisierte Array angehängt werden. Das Sprachkonstrukt isset () kann verwendet werden, um festzustellen, ob eine Variable bereits initialisiert wurde. Idealer und idealer ist außerdem die Lösung von empty (), da keine Warn- oder Fehlermeldung generiert wird, wenn die Variable nicht initialisiert wird.

Aus der PHP-Dokumentation :

Es wird keine Warnung generiert, wenn die Variable nicht vorhanden ist. Das bedeutet, dass empty () im Wesentlichen das prägnante Äquivalent zu ! Isset ($ var) || ist $ var == false .

Dies bedeutet , dass Sie nur verwenden können , empty()wenn die Variable bestimmen gesetzt und zusätzlich überprüft er die Variable gegen die folgenden 0, 0.0, "", "0", null, falseoder [].

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 im Online-PHP-Editor von 3v4l.org

Obwohl PHP keine Variablendeklaration erfordert, wird es empfohlen, um einige Sicherheitslücken oder Fehler zu vermeiden, bei denen vergessen würde, einer Variablen einen Wert zuzuweisen, der später im Skript verwendet wird. Was PHP im Fall von nicht deklarierten Variablen tut, ist ein sehr niedriger Fehler, der E_NOTICEnicht einmal standardmäßig gemeldet wird, aber das Handbuch empfiehlt, ihn während der Entwicklung zuzulassen .

Möglichkeiten, um mit dem Problem umzugehen:

  1. Empfohlen: Deklarieren Sie Ihre Variablen, z. B. wenn Sie versuchen, eine Zeichenfolge an eine undefinierte Variable anzuhängen. Oder verwenden Sie isset()/ !empty() , um zu überprüfen, ob sie deklariert sind, bevor Sie auf sie verweisen, 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'] : '';

    Ab PHP 7.0 ist dies viel sauberer geworden. Jetzt können Sie den Null-Koaleszenz-Operator verwenden :

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

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
  3. Deaktivieren Sie E_NOTICE für die Berichterstellung. Ein schneller Weg, um nur auszuschließen, E_NOTICEist:

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

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

Hinweis: Undefinierter Index / Undefinierter Offset

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

Möglichkeiten, um mit dem Problem umzugehen:

  1. Überprüfen Sie, ob der Index vorhanden ist, bevor Sie darauf zugreifen. Hierfü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 nicht vorhandenen Array-Index zuzugreifen:

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

Zwei Variablen werden verwendet, um auf zwei Array-Elemente zuzugreifen. Es gibt jedoch nur ein Array-Element, den Index 0. Dadurch wird Folgendes generiert:

Hinweis: Undefinierter Offset: 1

$_POST/ $_GET/ $_SESSIONVariablen

Die Hinweise oben erscheinen oft beim Arbeiten mit $_POST, $_GEToder $_SESSION. Für $_POSTund $_GETSie müssen nur überprüfen, ob der Index vorhanden ist oder nicht, bevor Sie sie verwenden. Denn $_SESSIONSie müssen sicherstellen, dass Sie die Sitzung gestartet haben session_start()und dass der Index auch existiert.

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

Verbunden:

Rizier123
quelle
7
@ dieselpower44 Ein paar Gedanken: Der "Shut-Up Operator" ( @) hat einige Leistungsprobleme. Da alle Fehler innerhalb eines bestimmten Bereichs unterdrückt werden, kann die sorgfältige Verwendung möglicherweise Nachrichten maskieren, die Sie gerne gesehen hätten.
IMSoP
6
Das Ausblenden der Probleme ist NICHT der Weg, um mit Problemen umzugehen. Die Elemente Nr. 2 ... Nr. 4 können nur auf Produktionsservern verwendet werden, nicht im Allgemeinen.
Salman A
1
Ist es möglich, die Nachricht inline (nicht im Handler) herunterzufahren, wenn auch ein benutzerdefinierter Fehlerhandler verwendet wird? $var = @$_GET['nonexisting'];verursacht immer noch Notiz ..
Alph.Dev
18
Warum wird empfohlen, 1. $value = isset($_POST['value']) ? $_POST['value'] : '';anstelle von 4. zu verwenden $value = @$_POST['value'];?
Forsvunnet
@twistedpixel Diese 4 Möglichkeiten sind unabhängig, das ist keine 4-Schritt-Anleitung. Wenn Sie sich also für Weg 4 entschieden haben, bedeutet dies, dass Sie die ersten 3 Wege nicht implementiert haben, sodass Sie noch keine Fehler unterdrückt haben.
Aycan Yaşıt
141

Probiere diese

Q1: Dieser Hinweis bedeutet, dass $ varname im aktuellen Bereich des Skripts nicht definiert ist.

F2: Die Verwendung der Bedingungen isset (), empty () vor der Verwendung einer verdächtigen 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:

Ish
quelle
Wenn Sie E_NOTICEaus der php.iniKonfigurationsdatei verwenden, tun Sieerror_reporting = (E_ALL & ~E_NOTICE)
ahmd0
Aufgrund der obigen Antwort habe ich isset, array_key_exists, ausprobiert, aber diese haben nicht funktioniert. Ich habe Ihre Antwort versucht, .empty (), und es funktioniert. Vielen Dank!
Ewef
63

Fehleranzeige @Operator

Für unerwünschte und redundante Benachrichtigungen könnte man den dedizierten @Operator verwenden , um undefinierte Variablen- / Indexnachrichten » auszublenden «.

$var = @($_GET["optional_param"]);
  • Dies wird normalerweise nicht empfohlen. Neulinge neigen dazu, es viel zu überbeanspruchen.
  • Es ist sehr ungeeignet für Code tief in der Anwendungslogik (nicht deklarierte Variablen werden ignoriert, wo Sie dies nicht tun sollten), z. B. für Funktionsparameter oder in Schleifen.
  • Es gibt jedoch einen Vorteil gegenüber der isset?:oder ??Super-Unterdrückung. Benachrichtigungen können weiterhin protokolliert werden. Und man kann @versteckte Notizen wiederbeleben mit:set_error_handler("var_dump");
    • Darüber hinaus sollten Sie if (isset($_POST["shubmit"]))Ihren ursprünglichen Code nicht gewöhnlich verwenden / empfehlen .
    • Neulinge werden solche Tippfehler nicht erkennen. Es beraubt Sie nur der PHPs Notices für genau diese Fälle. Hinzufügen @oder isseterst nach Überprüfung der Funktionalität.
    • Beheben Sie zuerst die Ursache. Nicht die Hinweise.

  • @ist hauptsächlich für $_GET/ $_POSTEingabeparameter akzeptabel , insbesondere wenn sie optional sind .

Und da dies die meisten dieser Fragen abdeckt, wollen wir auf die häufigsten Ursachen eingehen:

$_GET/ $_POST/ $_REQUESTUndefinierter Eingang

  • Wenn Sie auf einen undefinierten Index / Offset stoßen, müssen Sie zunächst nach Tippfehlern suchen:
    $count = $_GET["whatnow?"];

    • Ist dies ein erwarteter Schlüsselname und auf jeder Seitenanforderung vorhanden?
    • Variablennamen und Array-Angaben unterscheiden in PHP zwischen Groß- und Kleinschreibung.
  • Zweitens, wenn der Hinweis keine offensichtliche Ursache hat, verwenden var_dumpoder print_rüberprüfen Sie alle Eingabearrays auf ihren aktuellen Inhalt:

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

    Beide zeigen an, ob Ihr Skript mit den richtigen oder irgendwelchen Parametern aufgerufen wurde.

  • Alternativ oder verwenden Sie zusätzlich Ihren Browser devtools ( F12) und überprüfen Sie die Registerkarte Netzwerk auf Anforderungen und Parameter:

    Browser-Entwicklertools / Registerkarte "Netzwerk"

    POST-Parameter und GET-Eingang werden separat angezeigt.

  • Für $_GETParameter können Sie auch bei der Peek QUERY_STRINGin

    print_r($_SERVER);

    PHP hat einige Regeln zu verschmelzen Nicht-Standard - Parameternamen in die Superglobals. Apache könnte auch etwas umschreiben. Auf diese Weise können Sie auch die bereitgestellten Raw- $_COOKIESund anderen HTTP-Anforderungsheader anzeigen.

  • In der Adressleiste Ihres Browsers finden Sie GET-Parameter :

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

    Die name=valuePaare nach dem ?Fragezeichen sind Ihre Abfrageparameter (GET). Somit konnte diese URL möglicherweise nur $_GET["id"]und ergeben $_GET["sort"].

  • Überprüfen Sie abschließend Ihre <form>und<input> -Deklarationen, wenn Sie einen Parameter erwarten, aber keinen erhalten.

    • Stellen Sie sicher, dass jeder erforderliche Eingang einen hat <input name=FOO>
    • Das Attribut id=oder title=reicht nicht aus.
    • Ein method=POSTFormular sollte ausgefüllt werden $_POST.
    • Während a method=GET(oder es weglassen) $_GETVariablen ergeben würde .
    • Es ist auch möglich, dass ein Formular action=script.php?get=paramüber $ _GET und die verbleibenden method=POSTFelder in $ _POST nebenan bereitgestellt wird.
    • Mit modernen PHP-Konfigurationen (≥ 5,6) ist es möglich (nicht in Mode), sie $_REQUEST['vars']erneut zu verwenden , wodurch GET- und POST-Parameter kombiniert werden.
  • Wenn Sie mod_rewrite verwenden, sollten Sie sowohl die Parameter überprüfen access.logals auch aktivieren RewriteLog, um fehlende Parameter herauszufinden.

$_FILES

  • Die gleichen Integritätsprüfungen gelten für Datei-Uploads und $_FILES["formname"].
  • Überprüfen Sie außerdem auf enctype=multipart/form-data
  • Sowie method=POSTin Ihrer <form>Erklärung.
  • Siehe auch: PHP Undefined index error $ _FILES?

$_COOKIE

  • Das $_COOKIEArray wird nie direkt danach setcookie()gefüllt, sondern nur bei einer nachfolgenden HTTP-Anforderung.
  • Zusätzlich kann ihre Gültigkeitsdauer abgelaufen sein, sie können auf Subdomains oder einzelne Pfade beschränkt sein, und Benutzer und Browser können sie einfach ablehnen oder löschen.
Mario
quelle
2
Wenn Sie neugierig sind, wie sich die Leistung auswirkt, fasst dieser Artikel dies gut zusammen: derickrethans.nl/… .
Gajus
@GajusKuizinas Seit 2009 gab es einige Änderungen, insbesondere php.net/ChangeLog-5.php#5.4.0 ändert das Ergebnis drastisch (siehe "Zend Engine, Leistung" und "(Stille) Operator").
Mario
Danke @mario, interessant. Nun, wenn jemand gut genug war, um die beiden zu vergleichen ... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs Nach diesem Test scheinen sie identisch zu sein (beachten Sie, dass sich die Skala ändert).
Gajus
47

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

  1. Wenn es sich um einen Fehler handelt, weisen Sie der Variablen zuerst eine ordnungsgemäße Zuordnung zu: $ varname = 0;
  2. Wenn es wirklich nur manchmal definiert ist, testen Sie es: if (isset($varname))bevor Sie es verwenden
  3. Wenn es daran liegt, dass Sie es falsch geschrieben haben, korrigieren Sie das einfach
  4. Vielleicht sogar die Warnungen in Ihren PHP-Einstellungen ausschalten
Erik
quelle
5
Bitte schalten Sie Warnungen nicht aus. In strengeren Sprachen bedeuten sie oft "es könnte einen Fehler geben, überprüfen Sie diese Zeile besser zweimal" - in einer Sprache, die so freizügig ist wie PHP, bedeuten sie oft "dieser Code ist Mist und wahrscheinlich voller Fehler; ich werde versuchen, ihn zu machen." ein Gefühl dafür, aber Sie sollten dies so schnell wie möglich beheben ".
5
Obwohl ich den ersten drei Punkten zustimme, ist # 4 einfach falsch. Das Ausblenden eines Problems lässt es nicht verschwinden, und es kann später sogar zu weiteren Problemen führen.
Valentin Flachsel
1
@Freek absolut wahr, aber in einigen Szenarien (Gekauftes Skript, kein technisches Wissen, muss es bis morgen laufen ...) ist es die Klebebandlösung - wirklich schlecht, die immer betont werden muss, aber eine Option
Pekka
Klebeband ist gut ... manchmal. In der Vergangenheit wurden Warnungen in Standard-PHP-Einstellungen deaktiviert, aber die Standardeinstellungen wurden strenger. Schade, dass viele zu den alten Einstellungen zurückkehren, um die Kunden nicht zu ärgern.
Erik
41

Dies bedeutet, dass Sie eine Variable testen, auswerten oder drucken, der Sie noch nichts zugewiesen haben. Dies bedeutet, dass Sie entweder einen Tippfehler haben oder zuerst überprüfen müssen, ob die Variable mit etwas initialisiert wurde. Überprüfen Sie Ihre Logikpfade. Möglicherweise wird sie in einem Pfad festgelegt, jedoch nicht in einem anderen.

DGM
quelle
34

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

Meine Lösung war diese Funktion:

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

Wenn ich also auf $ name und echo verweisen möchte, falls vorhanden, 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')?>
Ferenci Zoltán László
quelle
2
Ihre ifexists () -Funktion funktioniert in PHP 5.3 nicht für mich. Die Variablen des Anrufers sind in der Funktion des lokalen Bereich (siehe nicht verfügbar Variable Umfang ), es sei denn , sie sind Superglobals oder Sie Geige mit $ GLOBALS , so $foo = "BABAR"; ifexists('foo');wird im allgemeinen null zurück. (Kursivschrift ist php.net Kapitel.)
Skifahrerseite
Jetzt bekommst du "Hallo von" ... was ist der Sinn? Überprüfen Sie einfach den Wertif( !empty($user) and !empty($location) ) echo "hello $user ..."
GCB
27

Der beste Weg , Eingang für das Erhalten Zeichenfolge ist:

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

Dieser Einzeiler entspricht fast:

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

Wenn Sie unbedingt einen Zeichenfolgenwert wünschen , gehen Sie wie folgt vor:

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

Dies liegt daran, dass die Variable '$ user_location' nicht definiert wird. Wenn Sie eine if-Schleife verwenden, in der Sie die Variable '$ user_location' deklarieren, müssen Sie auch eine else-Schleife haben und diese definieren. Zum Beispiel:

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

Der obige Code erzeugt einen Fehler, da die if-Schleife nicht erfüllt ist und in der else-Schleife '$ user_location' nicht definiert wurde. Trotzdem wurde PHP gebeten, die Variable wiederzugeben. Um den Code zu ändern, müssen Sie Folgendes tun:

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

Als Antwort auf "" Warum erscheinen sie plötzlich? Ich habe dieses Skript jahrelang verwendet und hatte nie ein Problem. "

Es ist sehr üblich, dass die meisten Websites unter der "Standard" -Fehlermeldung "Alle Fehler anzeigen, aber nicht" Hinweise "und" Veraltet "" arbeiten. Dies wird in der php.ini festgelegt und gilt für alle Sites auf dem Server. Dies bedeutet, dass die in den Beispielen verwendeten "Hinweise" unterdrückt (ausgeblendet) werden, während andere Fehler, die als kritischer angesehen werden, angezeigt / aufgezeichnet werden.

Die andere kritische Einstellung ist, dass die Fehler ausgeblendet werden können (dh display_errorsauf "Aus" oder "Syslog" gesetzt).

Was in diesem Fall passiert ist, ist, dass entweder das error_reportinggeändert wurde, um auch Hinweise display_errorsanzuzeigen (wie in den Beispielen), und / oder dass die Einstellungen auf dem Bildschirm geändert wurden (anstatt sie zu unterdrücken / zu protokollieren).

Warum haben sie sich verändert?

Die offensichtliche / einfachste Antwort ist, dass jemand eine dieser Einstellungen in php.ini angepasst hat oder eine aktualisierte Version von PHP jetzt eine andere php.ini als zuvor verwendet. Das ist der erste Ort, an dem man suchen muss.

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

  • .htconf (Webserverkonfiguration, einschließlich vhosts und Subkonfigurationen) *
  • .htaccess
  • im PHP-Code selbst

und jedes davon könnte auch geändert worden sein.

Es gibt auch die zusätzliche Komplikation, dass die Webserverkonfiguration .htaccess-Direktiven aktivieren / deaktivieren kann. Wenn Sie also Direktiven in .htaccess haben, die plötzlich starten / aufhören zu arbeiten, müssen Sie dies überprüfen.

(.htconf / .htaccess gehen davon aus, dass Sie als Apache ausgeführt werden. Wenn Sie die Befehlszeile ausführen, gilt dies nicht. Wenn Sie IIS oder einen anderen Webserver ausführen, müssen Sie diese Konfigurationen entsprechend überprüfen.)

Zusammenfassung

  • Check error_reportingund display_errorsPHP-Anweisungen in der php.ini haben sich nicht geändert oder Sie verwenden keine andere php.ini als zuvor.
  • Prüfen error_reportingund display_errorsPHP - Richtlinien in .htconf (oder vhosts usw.) haben sich nicht geändert
  • Check- error_reportingund display_errorsPHP-Anweisungen in .htaccess haben sich nicht geändert
  • Wenn Sie eine Direktive in .htaccess haben, überprüfen Sie, ob diese in der .htconf-Datei noch zulässig sind
  • Überprüfen Sie abschließend Ihren Code. möglicherweise eine nicht verwandte Bibliothek; um zu sehen, ob error_reportingund display_errorsPHP-Direktiven dort gesetzt wurden.
Robbie
quelle
20

Die schnelle Lösung besteht darin, Ihre Variable oben im Code auf Null zu setzen

$user_location = null;
Shahin Mammadzada
quelle
16

Früher habe ich diesen Fehler verflucht, aber es kann hilfreich sein, Sie daran zu erinnern, Benutzereingaben zu entgehen.

Wenn Sie zum Beispiel dachten, dies sei ein cleverer Kurzcode:

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

...Denk nochmal! Eine bessere Lösung ist:

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

(Ich verwende eine benutzerdefinierte html()Funktion, um Zeichen zu entkommen. Ihr Kilometerstand kann variieren.)

rybo111
quelle
15

In PHP 7.0 ist es jetzt möglich, den Null-Koaleszenzoperator zu verwenden:

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

Ist gleich:

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

PHP Handbuch PHP 7.0

elpiel
quelle
Dies funktioniert auch gut in if-Anweisungen. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
Ein Codierer
Ihr Code ist eigentlich ein schöner übersehener Fehler: ?? - prüft nur isset(), ob Sie bestanden haben is_array()- was ein boolesches, unerwartetes Verhalten ist.
Elpiel
14

Ich benutze die eigene nützliche Funktion exst (), die automatisch Variablen deklariert.

Ihr Code lautet -

$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;
}
user2253362
quelle
14

In einer sehr einfachen Sprache .
Der Fehler ist, dass Sie eine Variable verwenden, $user_locationdie zuvor nicht von Ihnen definiert wurde und keinen Wert hat. Ich empfehle Ihnen daher , diese Variable vor der Verwendung zu deklarieren. Beispiel:


$user_location = '';
Oder
$user_location = 'Los Angles';
Dies ist ein sehr häufiger Fehler, dem Sie begegnen können. Machen Sie sich also keine Sorgen, deklarieren Sie einfach die Variable und genießen Sie die Codierung .

Rishabh Seth
quelle
8

Warum nicht einfach halten?

<?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
quelle
8

WARUM PASSIERT DIES?

Im Laufe der Zeit hat sich PHP zu einer sicherheitsorientierteren Sprache entwickelt. Einstellungen, die früher standardmäßig deaktiviert waren, sind jetzt standardmäßig aktiviert. Ein perfektes Beispiel hierfür ist E_STRICT, dass es ab PHP 5.4.0 standardmäßig aktiviert wurde .

Darüber hinaus ist laut PHP-Dokumentation E_NOTICEin der php.ini standardmäßig deaktiviert. PHP-Dokumente empfehlen , es für Debugging-Zwecke zu aktivieren . Wenn ich jedoch PHP aus dem Ubuntu-Repository und vom Windows-Stack von BitNami herunterlade, sehe ich etwas anderes.

; 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

Beachten Sie, dass error_reportingder Standardwert standardmäßig auf den Produktionswert und nicht standardmäßig auf den Standardwert eingestellt ist. Dies ist etwas verwirrend und wird nicht außerhalb von php.ini dokumentiert, daher habe ich dies bei anderen Distributionen nicht validiert.

Um Ihre Frage zu beantworten, wird dieser Fehler jetzt angezeigt, wenn er zuvor nicht angezeigt wurde, weil:

  1. Sie haben PHP installiert und die neuen Standardeinstellungen sind etwas schlecht dokumentiert, schließen sie jedoch nicht aus E_NOTICE.

  2. E_NOTICEWarnungen wie undefinierte Variablen und undefinierte Indizes tragen tatsächlich dazu bei, Ihren Code sauberer und sicherer zu machen. Ich kann Ihnen sagen, dass ich vor Jahren E_NOTICEgezwungen war, meine Variablen zu deklarieren, wenn ich aktiviert blieb. Es machte es viel einfacher, C zu lernen, wenn man nicht deklariert, dass Variablen viel störender sind.

WAS KANN ICH TUN?

  1. Deaktivieren Sie diese Option, E_NOTICEindem Sie den "Standardwert" kopieren E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATEDund durch den derzeit nicht kommentierten Wert ersetzen, nachdem Sie sich gleich angemeldet haben error_reporting =. Starten Sie Apache oder PHP neu, wenn Sie CGI oder FPM verwenden. Stellen Sie sicher, dass Sie die "richtige" php.ini bearbeiten. Das richtige ist Apache, wenn Sie PHP mit Apache ausführen, fpm oder php-fpm, wenn Sie PHP-FPM ausführen, cgi, wenn Sie PHP-CGI ausführen usw. Dies ist nicht die empfohlene Methode, aber wenn Sie Legacy-Code haben, der dies tun wird Wenn es äußerst schwierig ist, es zu bearbeiten, ist es möglicherweise die beste Wahl.

  2. Deaktivieren Sie E_NOTICEauf Datei- oder Ordnerebene. Dies ist möglicherweise vorzuziehen, wenn Sie über Legacy-Code verfügen, die Dinge aber ansonsten "richtig" ausführen möchten. Wenden Sie sich dazu an Apache2, Nginx oder einen Server Ihrer Wahl. In Apache würden Sie php_valueinnerhalb von verwenden <Directory>.

  3. Schreiben Sie Ihren Code neu, um sauberer zu sein. Wenn Sie dies tun müssen, während Sie in eine Produktionsumgebung wechseln oder nicht möchten, dass jemand Ihre Fehler sieht, stellen Sie sicher, dass Sie die Fehleranzeige deaktivieren und nur Ihre Fehler protokollieren (siehe display_errorsund log_errorsin der php.ini und Ihren Servereinstellungen). .

So erweitern Sie Option 3: Dies ist das Ideal. Wenn Sie diesen Weg gehen können, sollten Sie. Wenn Sie diese Route anfangs nicht verwenden, sollten Sie diese Route eventuell verschieben, indem Sie Ihren Code in einer Entwicklungsumgebung testen. Wenn Sie schon dabei sind, sollten Sie loswerden ~E_STRICTund ~E_DEPRECATEDsehen, was in Zukunft schief gehen könnte. Sie werden eine Menge ungewohnter Fehler sehen, aber es wird Sie davon abhalten, unangenehme Probleme zu haben, wenn Sie PHP in Zukunft aktualisieren müssen.

WAS BEDEUTEN DIE FEHLER?

Undefined variable: my_variable_name- Dies tritt auf, wenn vor der Verwendung keine Variable definiert wurde. Wenn das PHP-Skript ausgeführt wird, nimmt es intern nur einen Nullwert an. In welchem ​​Szenario müssten Sie jedoch eine Variable überprüfen, bevor sie definiert wurde? Letztendlich ist dies ein Argument für "schlampigen Code". Als Entwickler kann ich Ihnen sagen, dass ich es liebe, wenn ich ein Open-Source-Projekt sehe, bei dem Variablen in ihren Bereichen so hoch definiert sind, wie sie definiert werden können. Es macht es einfacher zu sagen, welche Variablen in Zukunft auftauchen werden, und es erleichtert das Lesen / Lernen des Codes.

function foo()
{
    $my_variable_name = '';

    //....

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

Undefined index: my_index- Dies tritt auf, wenn Sie versuchen, auf einen Wert in einem Array zuzugreifen, der nicht vorhanden ist. Führen Sie eine bedingte Prüfung durch, um diesen Fehler zu vermeiden.

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

Eine andere Möglichkeit besteht darin, ein leeres Array oben in Ihrer Funktion zu deklarieren. Dies ist nicht immer möglich.

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

//...

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

(zusätzlicher Tipp)

  • Als ich auf diese und andere Probleme stieß, verwendete ich NetBeans IDE (kostenlos) und es gab mir eine Vielzahl von Warnungen und Hinweisen. Einige von ihnen bieten sehr hilfreiche Tipps. Dies ist keine Voraussetzung und ich verwende keine IDEs mehr, außer für große Projekte. Ich bin vimheutzutage eher eine Person :).
smcjones
quelle
6

undefinierter Index bedeutet in einem Array, das Sie beispielsweise für einen nicht verfügbaren Array-Index angefordert haben

<?php 

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

?>

undefinierte Variable bedeutet, dass Sie eine vollständig nicht vorhandene Variable verwendet haben oder die beispielsweise nicht durch diesen Namen definiert oder initialisiert ist

<?php print_r($myvar); ?>

undefinierter Versatz bedeutet, dass Sie in einem Array nach einem nicht vorhandenen Schlüssel gefragt haben. Die Lösung hierfür besteht darin, dies vor dem Gebrauch zu überprüfen

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

Zu diesem Teil der Frage:

Warum tauchen sie plötzlich auf? Ich habe dieses Skript jahrelang benutzt und hatte nie ein Problem.

Keine eindeutigen Antworten, aber hier einige mögliche Erklärungen, warum sich Einstellungen "plötzlich" ändern können:

  1. Sie haben PHP auf eine neuere Version aktualisiert, die andere Standardeinstellungen für Fehlerberichterstattung, Anzeigefehler oder andere relevante Einstellungen enthalten kann.

  2. Sie haben Code entfernt oder eingeführt (möglicherweise in einer Abhängigkeit), der zur Laufzeit relevante Einstellungen mit ini_set()oder festlegt error_reporting()(suchen Sie diese im Code).

  3. Sie haben die Webserver-Konfiguration geändert (hier wird Apache angenommen): .htaccessDateien und vhost-Konfigurationen können auch die PHP-Einstellungen ändern.

  4. Normalerweise werden Benachrichtigungen nicht angezeigt / gemeldet (siehe PHP-Handbuch ), daher ist es möglich, dass beim Einrichten des Servers die Datei php.ini aus irgendeinem Grund nicht geladen werden konnte (Dateiberechtigungen ??) und Sie die Standardeinstellungen vorgenommen haben . Später wurde der 'Fehler' (aus Versehen) behoben und jetzt kann die richtige php.ini-Datei geladen werden, wobei error_reporting so eingestellt ist, dass Hinweise angezeigt werden.

Wouter de Winter
quelle
3

Wenn Sie mit Klassen arbeiten, müssen Sie sicherstellen, dass Sie auf Mitgliedsvariablen verweisen, indem Sie $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
quelle
3

Ein weiterer Grund, warum ein undefinierter Indexhinweis ausgelöst wird, ist, dass eine Spalte in einer Datenbankabfrage weggelassen wurde.

Dh:

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

Versuchen Sie dann, auf mehr Spalten / Zeilen innerhalb einer Schleife zuzugreifen.

Dh:

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

oder in einem while Schleife:

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

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

}

Etwas anderes, das beachtet werden muss, ist, dass unter * NIX OS und Mac OS X die Groß- und Kleinschreibung beachtet wird.

Konsultieren Sie die folgenden Fragen und Antworten zu Stack:

Fred -ii-
quelle
3

Mit einem ternären ist einfach, lesbar und sauber:

Pre PHP 7
Weisen Sie dem Wert einer anderen Variablen eine Variable zu, wenn diese festgelegt ist, andernfalls weisen Sie sie zunull(oder einen beliebigen Standardwert ):

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

PHP 7+
Das gleiche, außer dass der Null Coalescing Operator verwendet wird . Es ist kein Aufruf mehr erforderlich, isset()da dies integriert ist, und es ist nicht erforderlich, die zurückzugebende Variable anzugeben, da davon ausgegangen wird, dass der Wert der zu überprüfenden Variablen zurückgegeben wird:

$newVariable = $thePotentialData ?? null;

Beide stoppen die Mitteilungen aus der OP-Frage, und beide sind das genaue Äquivalent von:

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

 
Wenn Sie keine neue Variable festlegen müssen, können Sie den zurückgegebenen Wert des Ternärs direkt verwenden, z. B. mit echo , Funktionsargumente usw.:

Echo:

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

Funktion:

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

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

Das Obige funktioniert genauso mit Arrays, einschließlich Sitzungen usw., und ersetzt die zu prüfende Variable durch zB:
$_SESSION['checkMe']
oder wie viele Ebenen Sie benötigen, z.
$clients['personal']['address']['postcode']


 

Unterdrückung:

Es ist möglich, die PHP-Hinweise mit @Ihrer Fehlerberichterstattungsstufe zu unterdrücken oder zu reduzieren, aber es ist das Problem wird dadurch nicht behoben . Es wird lediglich die Meldung im Fehlerprotokoll gestoppt. Dies bedeutet, dass Ihr Code immer noch versucht hat, eine Variable zu verwenden, die nicht festgelegt wurde. Dies kann bedeuten, dass etwas nicht wie beabsichtigt funktioniert - je nachdem, wie wichtig der fehlende Wert ist.

Sie sollten wirklich nach diesem Problem suchen und es angemessen behandeln, indem Sie entweder eine andere Nachricht senden oder einfach nur einen Nullwert für alles andere zurückgeben, um den genauen Status zu ermitteln.

Wenn Sie sich nur darum kümmern, dass der Hinweis nicht im Fehlerprotokoll enthalten ist, können Sie das Fehlerprotokoll optional einfach ignorieren.

James
quelle
1

Eine häufige Ursache für eine Variable, die nach einem HTML- Code nicht vorhanden ist Formulars ist, ist, dass das Formularelement nicht in einem <form>Tag enthalten ist:

Beispiel: Element nicht im enthalten <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>

Beispiel: Element jetzt in der <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
quelle
0

Wahrscheinlich haben Sie bis dahin die alte PHP-Version verwendet und jetzt PHP aktualisiert. Dies ist der Grund, warum es seit Jahren fehlerfrei funktioniert hat. Bis PHP4 gab es keinen Fehler, wenn Sie eine Variable verwenden, ohne sie zu definieren, aber ab PHP5 werden Fehler für Codes ausgegeben, wie in Frage gestellt.

Phvish
quelle
0

Beim Umgang mit Dateien sind ein geeigneter Enctype und eine POST-Methode erforderlich, die einen undefinierten Indexhinweis auslösen, wenn beide nicht im Formular enthalten sind.

Das Handbuch enthält die folgende grundlegende Syntax:

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

?>

Referenz:

Funk Forty Niner
quelle
0

Ich habe eine Frage dazu gestellt und wurde mit der Nachricht auf diesen Beitrag verwiesen:

Diese Frage hat hier bereits eine Antwort:

"Hinweis: Undefinierte Variable", "Hinweis: Undefinierter Index" und "Hinweis: Undefinierter Offset" mit PHP

Ich teile meine Frage und Lösung hier:

Dies ist der Fehler:

Geben Sie hier die Bildbeschreibung ein

Zeile 154 ist das Problem. Das habe ich in Zeile 154:

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

Ich denke, das Problem ist, dass ich if-Bedingungen für die Variable schreibe $city, die nicht der Schlüssel, sondern der Wert in ist$key => $city . Können Sie zunächst bestätigen, ob dies die Ursache für die Warnung ist? Zweitens, wenn dies das Problem ist, warum kann ich dann keine Bedingung basierend auf dem Wert schreiben? Muss es mit dem Schlüssel sein, dass ich die Bedingung schreiben muss?

UPDATE 1: Das Problem ist, dass bei der Ausführung $citiesCounterArray[$key]manchmal der $keySchlüssel einem Schlüssel entspricht, der nicht im $citiesCounterArrayArray vorhanden ist, dies jedoch aufgrund der Daten meiner Schleife nicht immer der Fall ist. Ich muss eine Bedingung festlegen, damit $keyder Code ausgeführt wird, falls er im Array vorhanden ist. Andernfalls überspringen Sie ihn.

UPDATE 2: So habe ich es behoben mit array_key_exists():

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

Diese Fehler treten immer dann auf, wenn wir eine Variable verwenden, die nicht festgelegt ist.

Der beste Weg, um damit umzugehen, ist die Fehlerberichterstattung während der Entwicklung.

So setzen Sie die Fehlerberichterstattung auf:

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

Auf Produktionsservern ist die Fehlerberichterstattung deaktiviert, daher werden diese Fehler nicht angezeigt.

Auf dem Entwicklungsserver können wir jedoch die Fehlerberichterstattung festlegen.

Um diesen Fehler zu beheben, sehen wir das folgende Beispiel:

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

Wir können die Variablen initialisieren, NULLbevor wir ihre Werte zuweisen oder verwenden.

Wir können den Code also wie folgt ändern:

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

Dies stört keine Programmlogik und erzeugt keine Benachrichtigung, selbst wenn $testsie keinen Wert hat.

Grundsätzlich ist es immer besser, die Fehlerberichterstattung für die Entwicklung einzuschalten.

Und beheben Sie alle Fehler.

Und in der Produktion sollte die Fehlerberichterstattung deaktiviert sein.

Schüler
quelle
-1

Diese Hinweise sind darauf zurückzuführen, dass Sie die verwendete Variable nicht haben definedund der my_indexSchlüssel in der $my_arrayVariablen nicht vorhanden war .

Diese Benachrichtigungen wurden jedes Mal ausgelöst, weil Ihre codenicht korrekt sind, aber wahrscheinlich hatten Sie keine Meldung von Benachrichtigungen.

Lösen Sie die Fehler:

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

Ein anderer Weg, dies herauszubekommen:

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

In PHP benötigen Sie Faust, um die Variable zu definieren, danach können Sie sie verwenden.
Wir können überprüfen, ob die Variable auf sehr effiziente Weise definiert ist oder nicht!.

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

}

Einfache Erklärung

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