Cum se activează sau se dezactivează afișarea erorilor în PHP? Mesaje de eroare anterioare

02.04.2020 Știri


În tutorialul anterior, am acoperit elementele de bază ale gestionării excepțiilor și diferențele dintre excepții și erori. În această lecție vom studia procedurile de tratare a erorilor.


Erorile din PHP pot fi împărțite în erori de utilizator și de sistem. Din păcate, interceptați erori de sistem mijloace standard este imposibil și singura modalitate de a le face față este să scrieți și să depanați corect codul. Singurul lucru care poate (și ar trebui) să fie făcut este să împiedicați afișarea oricăror mesaje de eroare în browser. Acest lucru se face folosind funcția error_reporting(). Singurul parametru al acestei funcții determină ce erori pot fi trimise în browser.

Un parametru de funcție poate fi o combinație a următoarelor constante

Descriere constantă
E_EROARE Erori critice, întrerupând execuția scriptului (de exemplu, eroare de alocare a memoriei)
E_AVERTISMENT Avertizări
E_PARSE Erori de sintaxă a codului sursă
E_NOTIZARE Note
E_CORE_ERROR Erori critice care apar în timpul etapei de pornire a execuției scriptului
E_CORE_AVERTISMENT Avertismente care apar în timpul pornirii
E_COMPILE_ERROR Erori de compilare
E_COMPILE_WARNING Avertismente de compilare
E_USER_ERROR Erori utilizator, creat folosind funcția trigger_error().
E_USER_AVERTISMENT Avertismente personalizate create folosind funcția trigger_error().
E_USER_NOTICE Note personalizate create folosind funcția trigger_error().
E_TOȚI Toate posibile greșeli, avertismente și note
E_STRICT Note de rulare
E_RECOVERABLE_ERROR Erori critice care permit executarea ulterioară a codului.

De exemplu:

Uneori apar cazuri când este necesară dezactivarea ieșirii de eroare nu pentru întregul script, ci doar pentru o parte a acestuia. În acest caz, trebuie să utilizați operatorul de suprimare a erorilor „@” (câine). Când este plasat înaintea unei expresii, acest operator împiedică afișarea oricăror mesaje, avertismente sau notificări generate de expresie. De exemplu:

Erorile utilizatorului pot fi detectate și gestionate cu ușurință, iar gestionarea erorilor este concepută în așa fel încât să poată fi executată fără a se termina scriptul principal.

Pentru a genera o eroare, utilizați funcția trigger_error(), căreia îi trec doi parametri - tipul de eroare și textul său real. Tipul de eroare este determinat de constantele standard discutate mai sus.

De exemplu:

Apelarea funcției trigger_error nu duce la o terminare de urgență a scriptului, ceea ce înseamnă că tot codul următor va fi executat normal. Dacă este încă necesară întreruperea execuției, atunci programatorul trebuie să o facă „manual” folosind instrumente de limbaj.

Ca și în cazul excepțiilor, puteți instala propriul dvs. handler pentru erori. Acest lucru se face folosind funcția set_error_handler(), căreia i se transmite numele funcției de gestionare și o listă de tipuri de erori pentru care este apelată această funcție. Funcția are patru parametri: numărul erorii, textul erorii, numele fișierului și numărul rândului în care a apărut eroarea. De exemplu:

Dacă funcția de tratare a erorilor returnează true, atunci handlerul PHP intern nu este apelat, iar dacă este fals, atunci după ieșirea din procedura utilizator, eroarea va fi transmisă handler-ului intern standard. Acest lucru permite programatorului să răspundă doar la o parte din erorile care apar, restul lăsând la manevrele standard PHP.

Puteți restabili manerul anterior apelând funcția restore_error_handler():

În acest fel, puteți activa și dezactiva gestionarea erorilor după cum este necesar. Dar nu ar trebui să folosiți excesiv astfel de operațiuni - probabilitatea de a vă confunda și de a amesteca manipulatorii este prea mare. În cele mai multe cazuri, este suficient un singur handler, dar bine scris, care scrie erori într-un fișier jurnal sau într-o bază de date, le trimite la e-mailul administratorului și efectuează alte operațiuni utile.

Gestionarea erorilor este unul dintre cele mai importante elemente ale scripturilor. Un script prost scris poate deveni nu doar o durere de cap pentru un webmaster sau administrator de site. Scriptul „rău” (din cuvântul „bug” - eroare) reprezintă o amenințare serioasă de securitate. În mâinile unui hacker calificat, textul de eroare se transformă într-o cheie principală, permițând accesul la întregul conținut al site-ului și, probabil, la server.

O parte integrantă a programării este identificarea erorilor din cod. Chiar dacă un programator este un programator genial, tot va face greșeli, uneori chiar banale. Acest lucru este facilitat de natura umană însăși. Prin urmare, programatorul își petrece o mare parte din timp depanând și identificând erorile din cod. În consecință, cu cât instrumentele de identificare a erorilor în cod sunt mai flexibile și mai convenabile și cu cât programatorul le cunoaște mai bine, cu atât productivitatea lui este mai mare.

Deoarece PHP este un limbaj de programare de scripting, toate erorile făcute în cod sunt identificate pe măsură ce codul este executat. Un programator PHP va trebui să facă față atât erorilor standard inerente programării în general, cât și erorilor mai degrabă ascunse - cum ar fi greșelile de scriere în denumirea variabilelor.

Limbajul PHP oferă două mecanisme pentru detectarea erorilor dintr-un script în timpul execuției acestuia: mecanismul standard de eroare PHP și mecanismul de excepție. În PHP, o mulțime de funcționalități utilizează mecanismul de eroare standard, așa că este imposibil să nu știi despre asta. Prin urmare, acest articol se va concentra asupra acestui mecanism.

Mecanismul standard de eroare PHP este destul de simplu - dacă interpretul PHP întâmpină o eroare în timpul executării unui script, încearcă să informeze programatorul despre aceasta. Cu toate acestea, există destul de multe setări pentru acest mecanism, așa că este destul de dificil pentru un programator care cunoaște PHP să le înțeleagă.

Vedem erori

Deci, pentru ca PHP să afișeze erori direct pe pagină, trebuie să setați un parametru special în cod:

ini_set("erori_afișare", 1); //display_errors este responsabil pentru afișarea erorilor direct pe pagină. Dacă 0 – erorile nu sunt afișate

Acum, dacă apare vreo eroare în script, interpretul va afișa informații despre aceasta pe pagină. De exemplu, dacă rulați un script cu o funcție inexistentă:

ini_set("erori_afișare", 1);
ecou"

Șir de afișat

";
echo abrakadabra();
ecou"

O linie care nu va fi afișată din cauza unei erori

";

atunci următoarea eroare va fi afișată pe pagină:

Eroare fatala. Acest tip de eroare înseamnă că scriptul este întrerupt și următorul cod nu va fi executat.

Afișarea erorilor de script pe pagină este folosită numai pentru a depana scriptul în sine, așa că atunci când rulează codul în producție, parametrul display_errors este setat la 0.

În general, în PHP există erori de diferite categorii de semnificație: unele dintre ele întrerup execuția ulterioară a codului - altele nu, unele pot fi interceptate - altele nu. O listă completă a categoriilor de erori este prezentată mai jos:

Sens
Constant
Descriere
Oportunitate
1
E_EROARE
Eroare fatala
Nu
2
E_AVERTISMENT
Eroare corectabilă
da
4
E_PARSE
Eroare de analizare
Nu
8
E_NOTIZARE
Potențială eroare
da
16
E_CORE_ERROR
Similar cu E_ERROR, dar generat de nucleul PHP
Nu
32
E_CORE_AVERTISMENT
Similar cu E_WARNING, dar generat de nucleul PHPNu
64
E_COMPILE_ERROR
Similar cu E_ERROR, dar generat de Zend Engine
Nu
128
E_COMPILE_WARNING
Similar cu E_WARNING, dar generat de Zend EngineNu
256
E_USER_ERROR
Similar cu E_ERROR, dar declanșat prin apelarea trigger_error()
da
512
E_USER_AVERTISMENT
Similar cu E_WARNING, dar declanșat prin apelarea trigger_error()da
1024
E_USER_NOTICE
Similar cu E_NOTICE, dar declanșat prin apelarea trigger_error()da
2048
E_STRICT
Mesaj din runtime cu recomandări pentru îmbunătățirea calității codului (începând cu PHP5)
-
4096
E_RECOVERABLE_ERROR
Eroare periculoasă, dar nu fatală (de exemplu, nepotrivire de tip)
da
8192
E_DEPRECATED
Avertisment de funcționalitate sau caracteristică depreciată
da
16384
E_USER_DEPRECATED
Funcție depreciată sau avertisment de caracteristică afișat în cod
da
32767
E_TOȚI
Toate erorile
Nu

Pentru comoditate, sunt furnizate constante care sunt utilizate pentru a determina nivelul de procesare a erorilor și pentru a construi o mască de biți. Constantele au nume semnificative. Privind constanta - putem spune că eroarea de nivel E_PARSE apare în cazul unei erori de sintaxă, E_NOTICE este un memento pentru programator despre încălcarea „stilului bun” al programării PHP.

În mod implicit, modul de generare a mesajelor de eroare este E_ALL & ~E_NOTICE, care corespunde ieșirii tuturor mesajelor care nu sunt clasificate ca E_NOTICE. Programatorul poate configura în mod flexibil ce categorii de erori trebuie să vadă pe pagină. Pentru a schimba modul de generare a erorilor, trebuie să modificați parametrul de configurare error_reporting. Pentru a activa afișarea oricăror erori, trebuie să setați acest parametru la E_ALL :

De exemplu, dacă rulați următorul cod:

ini_set("erori_afișare", 1);
ini_set("raportare_eroare", E_ALL);

Vom primi erori de două categorii simultan (notizare și avertisment):

Când este utilizată o variabilă nedeclarată, apare o eroare E_NOTICE. La conectarea la bază Date MySQL(sau altul) eșuează - interpretul PHP raportează o eroare E_WARNING.

Erori de înregistrare

Chiar dacă parametrul de configurare display_errors este setat la 0, ar trebui să fie posibil să se vadă dacă au apărut erori în timpul execuției scriptului. Astfel, dacă apare o eroare, trebuie să știm unde și de ce s-a întâmplat. În aceste scopuri, PHP are setări de înregistrare a erorilor.

În mod implicit, înseamnă limbaj PHP erorile nu sunt înregistrate nicăieri. Pentru a schimba acest lucru, trebuie să modificați parametrul de configurare log_errors la 1 de la 0:

ini_set("log_erori", 1);

În acest caz, erorile vor fi scrise automat în fișierul specificat în parametrul de configurare error_log. Parametrul error_log poate fi modificat și prin specificarea căii către fișierul dorit în care vor fi înregistrate erorile:

ini_set("log_error", "/var/log/php_errors.log");

Deci, pentru cod:

ini_set("erori_afișare", 1);
ini_set("raportare_eroare", E_ALL);
ini_set("log_erori", 1);
ini_set("log_eroare", __DIR__ . "/log.txt");
$db = mysql_connect($db_host, „utilizator”, „parolă”);

Informații similare sunt înregistrate în fișierul jurnal și afișate pe pagină:

Notificare PHP: Variabilă nedefinită: db_host în Z:\home\test\www\index.php pe linia 7
Avertisment PHP: mysql_connect(): Acces refuzat utilizatorului „user”@“localhost” (folosind parola: YES) în Z:\home\test\www\index.php pe linia 7

Manevrarea erorilor

Erorile sunt împărțite în catchable și non-catchable. Erorile non-fatale pot fi detectate de codul utilizatorului. Masă rotativă descrierile categoriilor de erori dezvăluie informații despre categoriile de erori care pot fi detectate.

Pentru a prinde erorile non-critice din cod, este suficient să implementați și să declarați propria funcție și să îi transmiteți numele funcției set_error_handler. În acest caz, 5 parametri sunt trecuți funcției implementate:

  • nivelul de eroare ca număr întreg;
  • mesaj de eroare ca șir;
  • numele fișierului în care a apărut eroarea, sub formă de șir;
  • numărul liniei în care a apărut eroarea, ca număr întreg;
  • o matrice cu toate variabilele care există în domeniul în care a apărut eroarea. Mai mult, vor fi incluse și variabile globale.
,

Concluzie

PHP are instrumente puternice pentru gestionarea și gestionarea propagării erorilor standard. Prin urmare, prinderea cutare sau cutare eroare nu va fi dificilă, cu condiția ca scriptul să fie configurat corect. Cunoașterea acestui domeniu este parte integrantă a oricărui programator PHP, deoarece o mulțime de coduri utilizează mecanismul descris mai sus


Am auzit adesea despre această problemă de la alți utilizatori. Unii, din cauza hosterului, trebuie să ascundă erorile care apar, alții, dimpotrivă, trebuie să înțeleagă ce se întâmplă cu codul lor, pentru că nu este afișată o singură eroare. În acest articol voi încerca să arăt toate modalitățile principale de a afișa/ascunde erorile.

Într-un script PHP1) Există un singur operator în PHP care acceptă sistemul de gestionare a erorilor - semnul @. Vă permite să ignorați orice mesaj de eroare. Trebuie plasat ÎNAINTE unei expresii care o poate conține.

Există o eroare deliberată în exemplu, dar aceasta NU va fi afișată

$valoare = @$var[$cheie];
2) De asemenea, puteți introduce o setare pentru parametrul de afișare a erorilor (display_errors) înainte ca scriptul PHP să fie verificat. Poate lua valoarea fie Pornit (afișare) fie Off (ascunde).

Ini_set("display_errors","On");
error_reporting ("E_ALL");
Și, în consecință, după codul care a fost verificat pentru erori, setați parametrul înapoi.

Ini_set("display_errors","Off");

De exemplu, doriți să vedeți erori în script

Ini_set("erori_afișare", "Activat"); // vor fi afișate mesaje de eroare
raportare_erori(E_ALL); // E_ALL - afișează TOATE erorile
$valoare = $var[$cheie]; // exemplu de eroare
ini_set("erori_afișare", "Oprit"); // acum nu vor fi mesaje
Îl puteți seta invers (dezactivat în partea de sus și activat în jos), astfel încât erorile să NU fie afișate într-o anumită secțiune a codului.

În fișierul .htaccess Cel mai adesea, problema se rezolvă prin specificarea setărilor în fișierul .htaccess, care se află în directorul rădăcină al site-ului. În linia php_flag display_errors trebuie, de asemenea, să setați On sau Off

Php_flag display_errors Activat
#afișați toate erorile, cu excepția avertismentelor (Notă)
php_value error_reporting „E_ALL & ~E_NOTICE”

În fișierul php.ini După cum puteți vedea, parametrul poate fi specificat în mai multe locuri. Totuși, dacă doriți ca acest parametru să aibă o anumită valoare pe întregul site, atunci este mai ușor să îl setați în fișierul php.ini (s-ar putea să nu fie întotdeauna accesibil pe găzduire), dar în acest caz puteți chiar să ocoliți setările întregii găzduiri

În php.ini:

Error_reporting = E_ALL
display_errors Activat
ÎN linia de sus Selectăm toate tipurile de erori, iar în partea de jos dăm voie pentru afișarea lor.

După editări, trebuie să reporniți Apache pentru ca setările să fie modificate și să aibă efect (grațios sau reporniți):

Sudo apachectl -k grațios

În ce ordine este procesat parametrul de eroare La început se ia în calcul parametrul php.ini, apoi .htaccess, iar apoi ce este specificat direct în scriptul PHP. Deci, dacă ceva nu funcționează, atunci caută în sus, poate că există o altă setare acolo.

Ca întotdeauna, vă mulțumesc pentru atenție și mult succes! Sper că articolul a fost de folos!

    Intenționat:

    • print, eco și alte funcții care produc rezultate
    • Secțiunile neprocesate precedente

      Dacă sursa erorii este menționată ca fiind închisă?> atunci un text lipsă sau neprocesat este scris aici. Marcatorul de sfârșit PHP nu încheie execuția scriptului în acest moment. Orice caractere de text/spațiu după ce au fost scrise ca conținut de pagină până acum.

      Este în general acceptat, în special printre începători, că etichetele de închidere ?> PHP ar trebui să fie omise. Acest lucru previne o mică parte din aceste cazuri. (De cele mai multe ori, scripturile include()d sunt vinovate.)

    • Sursa de eroare listată ca „Necunoscută la linia 0”

      De obicei, aceasta este o extensie PHP sau php.ini dacă sursa erorilor este specifică.

      • Uneori, opțiunea de configurare a fluxului este gzip sau ob_gzhandler .
      • Dar acesta ar putea fi orice modul încărcat de două ori extensie= care generează un mesaj implicit de pornire/avertizare PHP.
    • Mesaje de eroare anterioare

      Dacă alt operator sau Expresia PHP determină tipărirea unui avertisment sau a unei notificări, care este, de asemenea, considerată o ieșire prematură.

      În acest caz, trebuie să evitați eroarea, să întârziați execuția instrucțiunii sau să suprimați mesajul, de exemplu. isset() sau @() - când nici unul nu împiedică depanarea mai târziu.

    Niciun mesaj de eroare

    Dacă aveți error_reporting sau display_errors dezactivate în php.ini, atunci avertismentul nu va apărea. Dar ignorarea erorilor nu va duce problema departe. Anteturile încă nu pot fi trimise după plecarea devreme.

    Prin urmare, atunci când antetul ("Locație: ...") redirecționează în tăcere, se recomandă monitorizarea avertismentelor. Desemnați-le cu două comenzi simple pentru a apela scriptul:

    Raportare_eroare(E_ALL); ini_set("erori_afișare", 1);

    Sau set_error_handler("var_dump"); , dacă toate celelalte nu reușesc.

    Când vorbim despre redirecționările antetului, ar trebui să utilizați adesea un mod ca acesta pentru căile finale ale codului:

    Exit(header("Locație: /finished.html"));

    De preferință, chiar și o funcție de utilitate care imprimă mesajul utilizatorului dacă header() eșuează.

    Buffering de ieșire ca o soluție

    Poate ascunde spații albe pentru ieșirea HTML. Dar de îndată ce aplicația încearcă în mod logic să trimită conținut binar (cum ar fi o imagine generată), ieșirea străină tamponată devine o problemă. (Este nevoie de ob_clean() ca și opțiunea anterioară.)

    Buffer-ul este limitat în dimensiune și poate depăși cu ușurință dacă este lăsat în mod implicit. Și acest lucru nu este neobișnuit, este dificil de urmărit când se întâmplă acest lucru.

    Ambele abordări pot deveni nesigure - în special atunci când comutați între serverele de dezvoltare și/sau de producție. Acesta este motivul pentru care tamponarea de ieșire este considerată în general doar o cârjă/strict o soluție.

    Acest mesaj de eroare este declanșat atunci când ceva este trimis înainte ca anteturile HTTP să fie trimise (cu setcookie sau antet). Motive obișnuite pentru a imprima ceva înaintea antetelor HTTP:

      Spații aleatorii, adesea la începutul sau la sfârșitul fișierelor, de exemplu:

    Pentru a evita acest lucru, lăsați-l închis?>

    • Valorile octeților sunt octeții de la începutul fișierului php. Studiază-ți fișiere php prin utilizarea editor hexadecimal pentru a afla dacă acesta este cazul. Ele trebuie să înceapă cu octeții 3F 3C. Puteți elimina în siguranță specificația EF BB BF de la începutul fișierelor.
    • Ieșire explicită, cum ar fi apeluri la echo , printf , readfile , passthru , cod înainte de VERIFICAȚI ȘI AICI SPAȚII ALTE; ACEASTĂ LINIE (linie goală) NU TREBUIE SĂ EXISTA.

      De cele mai multe ori, acest lucru ar trebui să rezolve problema dvs. Verificați toate fișierele legate de fișierul de care aveți nevoie.

      Notă. Uneori, un EDITOR (IDE), cum ar fi gedit (un editor Linux standard), adaugă o linie goală la fișierul de salvare salvat. Acest lucru nu ar trebui să se întâmple. Dacă utilizați Linux. puteți folosi editorul VI pentru a elimina spațiul/liniile după ?> la sfârșitul paginii.

      Dacă acest lucru nu este treaba dvs., atunci puteți utiliza ob_start pentru a tampona ieșirea, așa cum se arată mai jos:

      Soluție posibilă 2:

      Acest lucru va salva rezultatul și anteturile dvs. vor fi create după ce pagina este tamponată.

      În loc de linia de mai jos

      //header("Locație:".ADMIN_URL."/index.php");

      scrie

      Echo("location.href = "".ADMIN_URL."/index.php?msg=$msg";");

      ?>