php error - Kann ich versuchen / eine Warnung abfangen?




handling best (9)

Seien Sie vorsichtig mit dem @ -Operator - während er Warnungen unterdrückt, unterdrückt er auch schwerwiegende Fehler. Ich habe viel Zeit damit verbracht, ein Problem in einem System zu debuggen, in dem jemand @mysql_query( '...' ) und das Problem war, dass die MySQL-Unterstützung nicht in PHP geladen war und einen stummen, fatalen Fehler verursachte. Es ist sicher für die Dinge, die Teil des PHP-Kerns sind, aber bitte verwenden Sie es mit Sorgfalt.

[email protected]:~$ php -a
Interactive shell

php > echo @something(); // this will just silently die...

Keine weitere Ausgabe - viel Glück beim Debuggen!

[email protected]:~$ php -a
Interactive shell

php > echo something(); // lets try it again but don't suppress the error
PHP Fatal error:  Call to undefined function something() in php shell code on line 1
PHP Stack trace:
PHP   1. {main}() php shell code:0
[email protected]:~$ 

Diesmal können wir sehen, warum es gescheitert ist.

Ich muss einige Warnungen einfangen, die von einigen php nativen Funktionen geworfen werden und sie dann behandeln.

Speziell:

array dns_get_record  ( string $hostname  [, int $type= DNS_ANY  [, array &$authns  [, array &$addtl  ]]] )

Es wird eine Warnung ausgegeben, wenn die DNS-Abfrage fehlschlägt.

try / catch funktioniert nicht, da eine Warnung keine Ausnahme darstellt.

Ich habe jetzt 2 Möglichkeiten:

  1. set_error_handler scheint übertrieben zu sein, weil ich es verwenden muss, um jede Warnung auf der Seite zu filtern (ist das wahr?);

  2. Passen Sie die Fehleranzeige / -anzeige so an, dass diese Warnungen nicht auf dem Bildschirm angezeigt werden, und überprüfen Sie dann den Rückgabewert. Wenn es false , werden keine Datensätze für Hostname gefunden.

Was ist die beste Vorgehensweise hier?


Normalerweise sollten Sie niemals @ verwenden, es sei denn, dies ist die einzige Lösung. In diesem speziellen Fall sollte die Funktion dns_check_record zuerst verwendet werden, um zu wissen, ob der Datensatz existiert.


versuchen Sie zu überprüfen, ob es einen booleschen Wert zurückgibt, dann können Sie es einfach als Bedingung setzen. Ich begegnete dem mit dem oci_execute (...), das mit meinen eindeutigen Schlüsseln einen Verstoß zurück gab.

ex.
oci_parse($res, "[oracle pl/sql]");
if(oci_execute){
...do something
}

Die Lösung, die wirklich funktioniert, stellte sich als einfacher Fehlerbehandler mit dem E_WARNING Parameter heraus:

set_error_handler("warning_handler", E_WARNING);
dns_get_record(...)
restore_error_handler();

function warning_handler($errno, $errstr) { 
// do something
}

Ich würde nur empfehlen, @ zu verwenden, um Warnungen zu unterdrücken, wenn es sich um eine direkte Operation handelt (zB $ prop = @ ($ high / ($ width - $ depth)); um Warnungen durch Division durch Null zu überspringen). In den meisten Fällen ist es jedoch besser zu handhaben.


Sie sollten wahrscheinlich versuchen, die Warnung vollständig zu entfernen, aber wenn das nicht möglich ist, können Sie den Anruf mit @ voranstellen (zB @dns_get_record (...)) und dann alle Informationen verwenden, die Sie herausfinden können, wenn die Warnung passiert ist oder nicht.


Ich wollte versuchen / eine Warnung abfangen, aber gleichzeitig die übliche Warnung / Fehlerprotokollierung behalten (zB in /var/log/apache2/error.log ); für die der Handler false . Da die Anweisung "throw new ..." die Ausführung jedoch grundsätzlich unterbricht, muss man den Trick "wrap in function" machen, der auch in

Gibt es eine statische Möglichkeit, Ausnahme in PHP zu werfen

Oder kurz gesagt:

  function throwErrorException($errstr = null,$code = null, $errno = null, $errfile = null, $errline = null) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
  }
  function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) {
    return false && throwErrorException($errstr, 0, $errno, $errfile, $errline);
    # error_log("AAA"); # will never run after throw
    /* Do execute PHP internal error handler */
    # return false; # will never run after throw
  }
  ...
  set_error_handler('warning_handler', E_WARNING);
  ...
  try {
    mkdir($path, 0777, true);
  } catch (Exception $e) {
    echo $e->getMessage();
    // ...
  }

EDIT: nach näherer Betrachtung stellt sich heraus, dass es nicht funktioniert: die " return false && throwErrorException ... " wird im Grunde nicht die Ausnahme return false && throwErrorException ... und nur das Fehlerprotokoll anmelden; das Entfernen des " false && " return throwErrorException ... , wie in " return throwErrorException ... ", wird die Ausnahme zum Werfen bringen, aber dann wird sich das error_log nicht einloggen ... Ich würde es trotzdem auf dem Laufenden halten, da Ich habe dieses Verhalten an anderer Stelle dokumentiert.


Wenn dns_get_record() fehlschlägt, sollte FALSE , sodass Sie die Warnung mit @ unterdrücken und dann den Rückgabewert überprüfen können.


Fatale Fehler oder wiederherstellbare schwerwiegende Fehler werfen jetzt Error in PHP 7 oder höheren Versionen . Wie bei allen anderen Ausnahmen können Fehlerobjekte mit einem try/catch Block abgefangen werden.

Beispiel:

<?php
$variable = 'not an object';

try {
    $variable->method(); // Throws an Error object in PHP 7 or higger.
} catch (Error $e) {
    // Handle error
    echo $e->getMessage(); // Call to a member function method() on string
}

https://3v4l.org/67vbk

Oder Sie können die Throwable Schnittstelle verwenden, um alle Ausnahmen Throwable .

Beispiel:

<?php
    try {
        undefinedFunctionCall();
    } catch (Throwable $e) {
        // Handle error
        echo $e->getMessage(); // Call to undefined function undefinedFunctionCall()
    }

https://3v4l.org/Br0MG

Für weitere Informationen: http://php.net/manual/tr/language.errors.php7.php







php error-handling