Situația actuală: PHP2Shell. Două vulnerabilități critice PHP (CVSS 9.2) permit cod malițios fără autentificare. Patchuri din 21.10.2026.Ce este de făcut acum →

Erori și excepții în PHP

PHP cunoaște mesaje de eroare clasice și excepții. Pagina explică ierarhia Throwable, tratarea curată a erorilor, setările sigure pentru producție și măsura PHP2Shell privind fatal_error_backtraces.

Stadiu 5 min de cititCunoștințe PHP

Pe scurt: PHP raportează problemele pe două căi: ca erori clasice, precum avertismente și notificări, controlate prin error_reporting, și ca excepții, care pot fi prinse cu try și catch. Din PHP 7, multe erori interne aruncă și ele un obiect al clasei Error; împreună cu Exception, aceasta implementează interfața Throwable. În producție se aplică regula: erorile se înregistrează în log, nu se afișează niciodată în browser. Pe PHP 8.5, din cauza PHP2Shell, fatal_error_backtraces=0 face parte în plus dintre măsurile de tranziție.

Două lumi: erori clasice și excepții

PHP provine dintr-o vreme în care erorile erau afișate mai ales ca mesaje: notificări (E_NOTICE), avertismente (E_WARNING), funcții depășite (E_DEPRECATED) și erori fatale (E_ERROR). Multe dintre aceste mesaje lasă scriptul să ruleze mai departe, adesea cu date greșite sau goale.

Excepțiile funcționează altfel. Ele întrerup desfășurarea normală și sar la următorul bloc catch potrivit. Dacă nu se găsește niciunul, scriptul se încheie. Pentru factorii de decizie, diferența este importantă: un avertisment tăcut poate duce la salvarea incompletă a unei comenzi, fără ca cineva să observe. O excepție face problema vizibilă și tratabilă.

Un beneficiu subestimat al mesajelor clasice sunt notificările de tip E_DEPRECATED. Ele anunță că un mijloc al limbajului dispare într-o versiune PHP viitoare. Cine le colectează în log și le evaluează regulat știe înainte de un upgrade ce locuri trebuie adaptate și nu trebuie să testeze îndelung abia în cazul unei vulnerabilități urgente.

Ierarhia Throwable

Tot ce poate fi aruncat cu throw și prins cu catch implementează Throwable. Dedesubt există două ramuri:

Clasă Scop Exemple de subclase
Exception erori previzibile ale aplicației și ale extensiilor ErrorException, PDOException, clase proprii
Error erori interne ale PHP TypeError, ValueError, ArgumentCountError, ArithmeticError, DivisionByZeroError, UnhandledMatchError

Clasele proprii de eroare derivă din Exception, nu din Error. Din PHP 8.0, majoritatea funcțiilor interne aruncă la parametri invalizi un TypeError sau ValueError, în loc să emită doar un avertisment. strlen([]) este un astfel de caz.

try, catch și finally în practică

<?php
declare(strict_types=1);

final class ZahlungFehlgeschlagen extends RuntimeException {}

function bezahlen(Bestellung $b, Zahlungsdienst $dienst, LoggerInterface $log): bool
{
    try {
        $dienst->belasten($b->betrag(), $b->referenz());
        return true;
    } catch (ZahlungFehlgeschlagen $e) {
        $log->warning('Zahlung abgelehnt', ['bestellung' => $b->id(), 'exception' => $e]);
        return false;
    } catch (TimeoutException | VerbindungsFehler) {
        // din PHP 8.0 variabila din catch este opțională
        $log->error('Zahlungsdienst nicht erreichbar', ['bestellung' => $b->id()]);
        return false;
    } finally {
        $dienst->verbindungSchliessen();
    }
}

Mai multe clase pot fi grupate într-un singur catch cu |. Blocul finally rulează întotdeauna, indiferent dacă a apărut o eroare sau nu. Din PHP 8.0, throw este în plus o expresie și poate sta, de exemplu, după ??: $id = $_GET['id'] ?? throw new InvalidArgumentException('id fehlt');.

Handlere globale: set_error_handler și set_exception_handler

Două funcții interceptează ceea ce altfel ar trece nebăgat în seamă. set_exception_handler() înregistrează o funcție pentru Throwable-urile neprinse. Potrivit manualului, scriptul se încheie după apelarea ei; este deci potrivită pentru înregistrare în log și o pagină de eroare neutră, nu pentru a continua munca.

S-a dovedit eficient un handler care scrie eroarea completă în log, cu momentul și un identificator aleatoriu, și arată vizitatorului doar o pagină neutră cu acest identificator. Suportul poate regăsi apoi cazul în log, fără ca detalii interne să ajungă în exterior.

set_error_handler() interceptează erorile clasice. Manualul arată cum pot fi transformate într-o ErrorException, astfel încât avertismentele să fie tratate ca excepții:

<?php
set_error_handler(function (int $nr, string $text, string $datei, int $zeile): bool {
    if (!(error_reporting() & $nr)) {
        return false; // exclus de error_reporting
    }
    if ($nr === E_DEPRECATED || $nr === E_USER_DEPRECATED) {
        return false; // nu escalada notificările despre elemente depășite
    }
    throw new ErrorException($text, 0, $nr, $datei, $zeile);
});

Erorile fatale, precum o depășire de memorie, nu pot fi interceptate pe această cale. Ce se întâmplă în interior la o depășire explică pagina memory_limit și Out-of-Memory.

Configurarea afișării erorilor și a înregistrării în log

Cele mai importante setări, cu valorile lor implicite potrivit manualului:

Setare Implicit Recomandare pentru producție
error_reporting E_ALL din PHP 8.0.0 E_ALL
display_errors 1 Off
display_startup_errors 1 din PHP 8.0.0 Off
log_errors 0 On
error_log gol (logul serverului web, respectiv al SAPI) fișier propriu, în afara webroot-ului
fatal_error_backtraces 1, nou în PHP 8.5.0 temporar 0 (PHP2Shell)

Din PHP 8.2.0, error_log_mode stabilește drepturile fișierului de log, implicit 0644. Dacă logurile conțin date personale sau căi, o valoare mai strictă este potrivită, ca alți utilizatori de pe server să nu le poată citi. Cu ignore_repeated_errors pot fi grupate mesajele identice din același fișier și de pe aceeași linie, pentru ca o buclă de erori să nu inunde logul.

Fișierul php.ini-production livrat setează deja display_errors pe Off. Potrivit manualului, ini_set('display_errors', ...) nu are efect la execuție asupra erorilor fatale, iar erorile de sintaxă apar înainte ca vreun ini_set() să ruleze. Aceste valori aparțin de aceea configurației serverului. Contextul se găsește în articolul Dezactivarea afișării erorilor în producție; cum se țin logurile fără scurgeri de date, în articolul Logare sigură.

Tratarea erorilor și PHP2Shell

Pentru PHP 8.5, php.net indică drept una dintre măsurile de tranziție împotriva PHP2Shell setarea fatal_error_backtraces=0 și repornirea ulterioară a PHP. Celelalte măsuri privesc memory_limit, post_max_size și session.upload_progress.enabled. Niciuna dintre ele nu înlocuiește actualizarea la PHP 8.5.12, 8.4.27, 8.3.36 sau 8.2.35.

; doar PHP 8.5, în php.ini sau în pool-ul FPM, apoi repornește toți workerii
fatal_error_backtraces = 0

Logurile de erori sunt, după PHP2Shell, și un important mijloc de probă. Dacă începând cu 20.10.2026 se înmulțesc erorile de memorie sau workerii întrerupți, aceasta poate indica tentative de atac, dar poate avea și cauze inofensive. Păstrați logurile și evaluați-le împreună cu logurile de acces, așa cum este descris în ghidul Analiza logurilor serverului web după un atac.

Cum ajută PHP SOS concret?

  • Verificăm setările efective pentru afișarea erorilor și înregistrarea în log, pentru fiecare site, și le configurăm potrivit pentru producție.
  • Aplicăm măsurile de tranziție PHP2Shell potrivite versiunii PHP și repornim toți workerii.
  • Securizăm logurile de erori și de acces începând cu 20.10.2026 și le analizăm pentru neregularități.
  • În cadrul monitorizării de securitate raportăm acumulările neobișnuite de erori, în loc să le lăsăm să se piardă în log.

Întrebări frecvente

Care este diferența dintre Error și Exception?

Ambele implementează interfața Throwable. Exception este gândită pentru erori pe care o aplicație le așteaptă și le tratează, de exemplu o conexiune eșuată la baza de date. Error reprezintă erori interne ale PHP, precum un TypeError sau o împărțire la zero.

Ar trebui display_errors să fie activat în producție?

Nu. Mesajele de eroare din browser dezvăluie căi, interogări și uneori date de acces. În producție, display_errors trebuie să fie Off și log_errors On, astfel încât erorile să ajungă în log, nu la vizitator.

Poate fi interceptată o depășire de memorie cu try/catch?

Nu. Dacă un script depășește memory_limit, PHP îl încheie cu o eroare fatală care nu poate fi prinsă ca excepție. Ea apare doar în logul de erori, dacă log_errors este activ.

Ce este fatal_error_backtraces?

O setare existentă din PHP 8.5.0, care adaugă un backtrace la erorile fatale. Este activă implicit. Ca măsură de tranziție împotriva PHP2Shell, php.net indică pentru PHP 8.5 setarea ei la 0 și repornirea ulterioară a PHP.

Surse

Contact imediat

Fiecare oră contează. Scrieți-ne acum.

Descrieți pe scurt sistemul, versiunea PHP și ce ați observat. Ne vom face auziți, clarificăm situația și lucrăm la distanță până când incidentul este încheiat și documentat.

Ajutor imediat