"Napomena: nedefinirana varijabla", "Napomena: nedefinirani indeks" i "Napomena: neograničeni pomak" pomoću PHP-a

Pokrećem PHP skriptu i nastavljam primati pogreške kao što su:

Napomena. Nedefinirana varijabla: my_variable_name u C: vampir mypath (index.php u retku 10)

Napomena. Nedefinirani indeks: my_index C: vampir mypath indeks.php u retku 11

Redovi 10 i 11 su sljedeći:

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

Što znači ove poruke o pogreškama?

Zašto se pojavljuju iznenada? Koristio sam ovu skriptu mnogo godina i nikad nisam imao nikakvih problema.

Kako ih popraviti?

Ovo je opće referentno pitanje za koje se ljudi mogu pozvati kao na duplikate, a ne na potrebu da se taj problem ponavlja iznova i iznova. Vjerujem da je to potrebno, jer je većina stvarnih odgovora na ovo pitanje vrlo specifična.

Povezana meta-rasprava:

982
24 нояб. postavljeno na Pekka 웃 24 Nov. 2010-11-24 00:26 '10 u 0:26 2010-11-24 00:26
@ 30 odgovora

Napomena. Nedefinirana varijabla

Iz opsežne mudrosti priručnika PHP :

Oslanjanje na zadanu vrijednost neinicijalizirane varijable problematično je ako je jedna datoteka uključena u drugu, koja koristi isto ime varijable. To je također ozbiljan sigurnosni rizik kada omogućite register_globals . Pogreška razine E_NOTICE izdaje se u slučaju rada s neinicijaliziranim varijablama, ali ne u slučaju dodavanja elemenata u neinicijalizirani niz. isset () se može koristiti za određivanje je li varijabla već inicijalizirana. Osim toga, rješenje empty () je idealnije jer ne generira upozorenje ili poruku o pogrešci ako varijabla nije inicijalizirana.

Iz PHP dokumentacije :

Upozorenje se ne generira ako varijabla ne postoji. To znači da je prazan () u biti kratak ekvivalent ! Isset ($ var) || $ var == false .

To znači da možete koristiti empty() da odredite je li varijabla postavljena, a osim toga, ona provjerava varijablu za sljedeće: 0,"",null .

primjer:

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

Testirajte navedeni fragment u online uredniku 3v4l.org

Iako PHP ne zahtijeva deklariranje varijable, preporučuje ga kako bi se izbjegle neke ranjivosti ili pogreške u sustavu, gdje možete zaboraviti dodijeliti vrijednost varijabli koja će se kasnije koristiti u skripti. Ono što PHP radi u slučaju neprijavljenih varijabli je pogreška niske razine, E_NOTICE , koja nije ni prijavljena prema zadanim postavkama, ali Vodič savjetuje da se to dopusti tijekom razvoja.

Načini rješavanja problema:

  1. Preporučuje se: deklarirati varijable, na primjer, kada pokušavate dodati niz u nedefiniranu varijablu. Ili upotrijebite isset() / !empty() da biste provjerili jesu li objavljeni prije njihove reference, na primjer:

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

    Postao je mnogo čišći s PHP 7.0, sada možete koristiti null coalesce operator :

     // Null coalesce operator - No need to explicitly initialize the variable. $value = $_POST['value'] ?? ''; 
  2. Instalirajte vlastiti alat za obradu pogrešaka za E_NOTICE i preusmjerite poruke sa standardnog izlaza (možda u datoteku dnevnika):

     set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT) 
  3. Onemogući E_NOTICE iz izvješća. Brz način isključivanja samo E_NOTICE :

     error_reporting( error_reporting()  ~E_NOTICE ) 
  4. Uklonite pogrešku pomoću @ operatora .

Napomena. Preporuča se primjena samo točke 1. \ t

Napomena: Nedefinirani indeks / nedefinirani pomak

Ta se obavijest pojavljuje kada Vi (ili PHP) pokušavate pristupiti nedefiniranom indeksu niza.

Načini rješavanja problema:

  1. Provjerite postoji li indeks prije nego ga dobijete. Da biste to učinili, možete koristiti isset() ili 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. list() konstrukcija list() može to generirati kada pokuša pristupiti indeksu niza koji ne postoji:

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

Za pristup dva elementa niza koriste se dvije varijable, ali postoji samo jedan element niza, indeks 0 , tako da će generirati:

Napomena: Neodređeni pomak: 1

$_POST / $_GET / $_SESSION varijabla

Gornje bilješke pojavljuju se često kada radite s $_POST , $_GET ili $_SESSION . Za $_POST i $_GET samo trebate provjeriti postoji li indeks prije korištenja. Za $_SESSION morate biti sigurni da je sesija pokrenuta sa session_start() i da indeks također postoji.

Također imajte na umu da su sve tri varijable superglobalne i imaju velika slova.

odnose:

901
24 нояб. Odgovor Alin Purcaru 24 Nov. 2010-11-24 00:36 '10 u 0:36 2010-11-24 00:36

Pokušajte s ovim

P1: Ova obavijest znači da $ varname nije definiran u trenutnom opsegu skripte.

Q2: Korištenje isset (), empty () uvjeta prije korištenja bilo koje sumnjive varijable dobro radi.

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

Ili kao brzo i prljavo rješenje:

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

Bilješka sesije:

112
24 нояб. odgovor je dat Ish 24 Nov. 2010-11-24 00:31 '10 u 0:31 2010-11-24 00:31

Pogreška pri prikazivanju @ operatora

Za neželjene i suvišne obavijesti možete koristiti namjenski @ operator za skrivanje "nedefiniranih poruka varijabli / indeksa".

 $var = @($_GET["optional_param"]); 
  • To je obično obeshrabrujuće. Početnici ih često zlostavljaju.
  • To je vrlo neprikladno za kod unutar logike aplikacije (zanemarivanje neprijavljenih varijabli u kojima ne morate), na primjer, za parametre funkcije ili u petljama.
  • Ima li jedan vrh iznad isset?: Ili ?? ipak super suzbijanje. Obavijesti se još uvijek mogu registrirati. A možete set_error_handler("var_dump"); @ -krivene obavijesti pomoću: set_error_handler("var_dump");
    • Osim toga, u izvornom kodu ne biste trebali normalno koristiti / recommend if (isset($_POST["shubmit"])) .
    • Početnici neće pronaći takve pogreške. Jednostavno vam oduzima PHP obavijesti za te slučajeve. Dodajte @ ili isset samo nakon provjere funkcionalnosti.
    • Prvo uklonite uzrok. Nema obavijesti.

  • @ je općenito prihvatljivo za ulazne parametre $_GET / $_POST , pogotovo ako su opcionalni.

Budući da ovo pokriva većinu ovih pitanja, dopustite mi da pokrijem najčešće razloge:

$_GET / $_POST / $_REQUEST nedefinirani unos

  • Prva stvar koju ćete učiniti kada se suočite s nedefiniranim indeksom / offsetom jest provjeriti pogreške pri upisu:
    $count = $_GET["whatnow?"];

    • Je li to očekivano ime ključa i prisutno je na svakom zahtjevu za stranicu?
    • U PHP-u nazivi varijabli i indeksi polja osjetljivi su na velika i mala slova.
  • Drugo, ako obavijest nema očiglednog razloga, koristite var_dump ili print_r za provjeru svih ulaznih polja za njihov trenutni sadržaj:

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

    Oba će pokazati je li vaša skripta ispisana s ispravnim ili bilo kojim parametrom.

  • Alternativno ili dodatno, koristite preglednik devtools ( F12 ) i provjerite mrežnu karticu za zahtjeve i parametre:

    2019

49
24 нояб. odgovor je dan mario 24 nov. 2010-11-24 00:40 '10 u 0:40 2010-11-24 00:40

To znači da testirate, procjenjujete ili ispisujete varijablu koju još niste dodijelili. To znači da ili imate pogrešku u unosu, ili morate provjeriti je li varijabla prvi put inicijalizirana. Provjerite logičke putanje, može se postaviti na jedan način, ali ne u drugom.

37
24 нояб. odgovor daje DGM 24.11. 2010-11-24 00:35 '10 u 0:35 2010-11-24 00:35

Općenito, zbog "lošeg programiranja" i mogućnosti grešaka sada ili kasnije.

  1. Ako je to pogreška, najprije napravite ispravnu dodjelu varijable: $ varname = 0;
  2. Ako je stvarno definiran samo povremeno, testirajte ga: if (isset($varname)) prije korištenja
  3. Ako je to zato što si to učinio krivo, samo popravi.
  4. Moguće je čak i rotirati upozorenja u PHP postavkama.
36
24 нояб. odgovor je dao erik 24 nov. 2010-11-24 00:31 '10 u 0:31 2010-11-24 00:31

Nisam htjela isključiti obavijest, jer je korisna, ali sam htjela izbjeći previše pisanja.

Moje rješenje je ta značajka:

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

Dakle, ako se želim osvrnuti na $ name i echo, ako postoji, samo pišem:

 <?=ifexists('name')?> 

Za elemente niza:

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

Na stranici, ako želim pogledati $ _REQUEST ['name']:

 <?=ifexistsidx($_REQUEST,'name')?> 
32
30 дек. Odgovor daje Ferenci Zoltán László 30. prosinca. 2011-12-30 17:14 '12 u 17:14 2011-12-30 17:14

Najbolji način da dobijete ulazni niz je :

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

Ova jednoredična linija gotovo je jednaka:

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

Ako apsolutno trebate vrijednost niza kao:

 $value = (string)filter_input(INPUT_POST, 'value'); 
25
27 авг. odgovor je dat mpyw 27 aug. 2014-08-27 01:15 '14 u 1:15 2014-08-27 01:15

Kao odgovor na “Zašto se pojavljuju iznenada? Koristio sam ovu skriptu mnogo godina, i nikada nisam imao nikakvih problema.

Za većinu web-mjesta često funkcionira u okviru zadane poruke o pogrešci "Prikaži sve pogreške, ali ne i" obavijesti "i" zastarjele ". To će biti instalirano u php.ini i odnosi se na sve web-lokacije na poslužitelju. obavijesti "korištene u primjerima bit će potisnute (skrivene), dok će se ostale pogreške smatrati kritičnijima.

Još jedan kritični parametar su pogreške koje se mogu sakriti (tj. display_errors postavljene su na "isključeno" ili "syslog").

Što se događa u ovom slučaju je da je ili error_reporting promijenjen tako da prikazuje obavijesti (u skladu s primjerima), i / ili su postavke promijenjene u display_errors na zaslonu (za razliku od suzbijanja / registriranja).

Zašto su se promijenili?

Očigledan / najjednostavniji odgovor je da je netko postavio bilo koju od ovih mogućnosti u php.ini, ili ažurirana verzija PHP-a sada koristi drugu php.ini od ranije. Ovo je prvo mjesto za gledanje.

Međutim, također možete poništiti ove postavke u

  • .htconf (konfiguracija web-poslužitelja, uključujući vhosts i pod-konfiguracije) *
  • .htaccess
  • u samom php kodu

i svaka od njih se također može promijeniti.

Tu je i dodatna komplikacija da konfiguracija web poslužitelja može omogućiti / onemogućiti .htaccess direktive, tako da ako imate direktive u .htaccess-u koje iznenada pokreću / zaustavljaju rad, morate to provjeriti.

(.htconf / .htaccess pretpostavlja da radite kao apache. Ako ne pokrenete naredbeni redak, ako koristite IIS ili neki drugi web poslužitelj, morat ćete u skladu s tim provjeriti ove konfiguracije)

rezime

  • Provjerite error_reporting u error_reporting i display_errors php uputama u php.ini ili da još ne koristite drugu php.ini.
  • Provjerite naredbe error_reporting i display_errors php u .htconf (ili vhosts, itd.) Nisu se promijenile
  • Provjerite error_reporting i display_errors php direktive u .htaccess nisu se promijenile
  • Ako imate naredbu u .htaccessu, provjerite je li dopuštena u .htconf datoteci.
  • Konačno, provjerite kod; vjerojatno nevezana knjižnica; vidjeti ako je smjernica php postavljena tamo od error_reporting i display_errors .
24
23 нояб. Odgovor daje Robbie 23. studenog. 2016-11-23 04:44 '16 u 4:44 2016-11-23 04:44

Budući da varijabla '$ user_location' nije definirana. Ako koristite bilo koju petlju if unutar koje deklarirate $ user_location varijablu, tada morate imati i loop i definirati isto. Na primjer:

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

Gornji kod će generirati pogrešku, jer petlja if se ne izvršava, a loop petlja ne definira '$ user_location'. Međutim, PHP je zamoljen da postavi varijablu. Stoga, da biste promijenili kôd, morate učiniti sljedeće:

 $a=10; if($a==5) { $user_location='Paris';} else { $user_location='SOMETHING OR BLANK'; } echo $user_location; 
24
29 дек. Odgovor je dao Roger 29. prosinca. 2012-12-29 14:46 '12 u 14:46 2012-12-29 14:46

Brzo rješenje postavlja varijablu na nulu na vrhu koda.

 $user_location = null; 
17
12 мая '14 в 22:02 2014-05-12 22:02 odgovor je dao Shahin Mammadzada 12. svibnja, 14 u 22:02 sati 2014-05-12 22:02

Pokušao sam proklinjati ovu pogrešku, ali možda će biti korisno podsjetiti vas da izbjegavate unos korisnika.

Na primjer, ako mislite da je ovo pametan, skraćeni kôd:

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

... Razmislite ponovo! Najbolje rješenje:

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

(Koristim prilagođenu funkciju html() za uklanjanje znakova, vaša kilometraža može varirati)

15
28 июля '15 в 22:12 2015-07-28 22:12 odgovor je dat rybo111 28. srpnja '15 u 22:12 sati 2015-07-28 22:12

Koristim cijelu korisnu funkciju vremena exst () , koja automatski deklarira varijable.

Vaš će kôd biti -

 $greeting = "Hello, ".exst($user_name, 'Visitor')." from ".exst($user_location);  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; } 
13
09 апр. odgovor daje korisnik2253362 09 travanj. 2013-04-09 16:43 '13 u 16:43 2013-04-09 16:43

Na vrlo jednostavnom jeziku .
Pogreška je da koristite varijablu $user_location , koju prethodno niste definirali, i nije važno. Stoga preporučujem da deklarirate ovu varijablu prije korištenja , na primjer:


$user_location = '';
ili
$user_location = 'Los Angles';
Ovo je uobičajena pogreška s kojom se možete susresti. Zato ne brinite, samo proglasite varijablu i uživajte u kodiranju .
13
18 дек. Odgovor je dao Rishabh Seth 18 prosinca. 2015-12-18 14:06 '15 u 14:06 2015-12-18 14:06

U PHP-u 7.0, sada možete koristiti Null-coalescing operatora:

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

jednakost:

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

PHP Vodič PHP 7.0

12
13 дек. Odgovor Lachezara Lecheva 13. prosinca 2016-12-13 16:34 '16 u 16:34 2016-12-13 16:34

Zašto se to dogodilo?

S vremenom je PHP postao više orijentiran na sigurnost. Postavke koje su prema zadanim postavkama onemogućene prema zadanim postavkama sada su omogućene po zadanom. Dobar primjer za to je E_STRICT , koji je prema zadanim postavkama omogućen kao PHP 5.4.0 .

Osim toga, prema PHP dokumentaciji defualt, E_NOTICE onemogućen u php.ini. PHP dokumenti preporučuju omogućavanje za svrhe otklanjanja pogrešaka . Međutim, kada učitam PHP iz skladišta Ubuntua i iz Bitnami stog sustava Windows, vidim nešto drugo.

 ; 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 

Imajte na umu da je zadana vrijednost error_reporting postavljena na vrijednost izvedenice, a ne na zadanu vrijednost. To je pomalo zbunjujuće i nije dokumentirano izvan php.ini, pa ga nisam provjerio na drugim distribucijama.

Da biste odgovorili na pitanje, ova se pogreška pojavljuje kada se nije pojavila ranije, jer:

  • Instalirali ste PHP, a nove zadane postavke pomalo su loše dokumentirane, ali ne isključuju E_NOTICE .

  • E_NOTICE upozorenja, kao što su nedefinirane varijable i nedefinirani indeksi, zaista pomažu da vaš kod postane čišći i sigurniji. Mogu reći da mi je prije nekoliko godina E_NOTICE podrška natjerala da proglasim svoje varijable. To je olakšalo proučavanje C-a, pri čemu je neobjavljivanje varijabli puno više problema.

ŠTO MOGU UČINITI OVE OVO?

  • Onemogućite E_NOTICE kopiranjem zadane vrijednosti E_ALL ~E_NOTICE ~E_STRICT ~E_DEPRECATED i zamijenite je s onim što je trenutno podijeljeno nakon znaka jednakosti u error_reporting = . Ponovno pokrenite Apache ili PHP ako koristite CGI ili FPM. Provjerite jeste li uredili "ispravnu" php.ini. Apache je ispravan ako koristite PHP s Apache, fpm ili php-fpm, ako koristite PHP-FPM, cgi, ako koristite PHP-CGI, itd. To nije preporučena metoda, ali ako imate zastarjeli kôd koji će biti iznimno teško urediti, to je možda vaš najbolji izbor.

  • Onemogućite E_NOTICE na razini datoteke ili mape. To je možda poželjnije ako imate neku vrstu naslijeđenog koda, ali inače želite učiniti nešto "ispravno". Da biste to učinili, trebate kontaktirati Apache2, nginx ili neovisno o poslužitelju. U Apacheu koristite php_value unutar <Directory> .

  • Ponovno napišite kod kako bi bio čišći. Если вам нужно сделать это при переходе в производственную среду или не хотите, чтобы кто-то видел ваши ошибки, убедитесь, что вы отключили отображение любых ошибок и только протоколирование ваших ошибок (см. display_errors и log_errors в php.ini и настройках вашего сервера).

Развернуть по опции 3: Это идеальный вариант. Если вы можете пойти по этому маршруту, вам нужно. Если вы не собираетесь на этом маршруте изначально, подумайте о том, чтобы переместить этот маршрут в конце концов, протестировав свой код в среде разработки. Пока вы на нем, избавьтесь от ~E_STRICT и ~E_DEPRECATED , чтобы увидеть, что может пойти не так в будущем. Вы увидите много незнакомых ошибок, но это остановит вас от каких-либо неприятных проблем, когда вам нужно обновить PHP в будущем.

ЧТО ОЗНАЧАЕТ ОШИБКИ?

Undefined variable: my_variable_name - Это происходит, когда переменная не была определена перед использованием. Когда выполняется PHP script, он внутренне просто принимает нулевое значение. Однако, в каком сценарии вам нужно было бы проверить переменную до ее определения? В конечном счете, это аргумент для "неаккуратного кода". Как разработчик, я могу сказать вам, что мне это нравится, когда я вижу проект с открытым исходным кодом, где переменные определены как высоко в своих областях, которые могут быть определены. Это облегчает определение того, какие переменные будут появляться в будущем, и упростит чтение/изучение кода.

 function foo() { $my_variable_name = ''; //.... if ($my_variable_name) { // perform some logic } } 

Undefined index: my_index - Это происходит, когда вы пытаетесь получить доступ к значению в массиве и его не существует. Чтобы предотвратить эту ошибку, выполните условную проверку.

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