2010-12-12 11 views
18

Im folgenden Beispiel, wenn die Klasse nicht existiert, möchte ich den Fehler abfangen und stattdessen eine Null Klasse erstellen.Warum fängt PHP nicht den Fehler "Klasse nicht gefunden" ab?

Aber trotz meiner Versuch/catch Aussagen, PHP sagt mir einfach Class 'SmartFormasdfasdf' not found.

Wie bekomme ich PHP, um den Fehler 'Klasse nicht gefunden' zu verstehen?

<?php 
class SmartFormLogin extends SmartForm { 
    public function render() { 
     echo '<p>this is the login form</p>'; 
    } 
} 

class SmartFormCodeWrapper extends SmartForm { 
    public function render() { 
     echo '<p>this is the code wrapper form</p>'; 
    } 
} 

class SmartFormNull extends SmartForm { 
    public function render() { 
     echo '<p>the form "' . htmlentities($this->idCode) . '" does not exist</p>'; 
    } 
} 

class SmartForm { 

    protected $idCode; 

    public function __construct($idCode) { 
     $this->idCode = $idCode; 
    } 

    public static function create($smartFormIdCode) { 
     $className = 'SmartForm' . $smartFormIdCode; 
     try { 
      return new $className($smartFormIdCode); 
     } catch (Exception $ex) { 
      return new SmartFormNull($smartformIdCode); 
     } 
    } 
} 

$formLogin = SmartForm::create('Login'); 
$formLogin->render(); 
$formLogin = SmartForm::create('CodeWrapper'); 
$formLogin->render(); 
$formLogin = SmartForm::create('asdfasdf'); 
$formLogin->render(); 
?> 

Lösung:

Dank @Mchl, das ist, wie ich es gelöst dann:

public static function create($smartFormIdCode) { 
    $className = 'SmartForm' . $smartFormIdCode; 
    if(class_exists($className)) { 
    return new $className($smartFormIdCode); 
    } else { 
    return new SmartFormNull($smartFormIdCode); 
    } 
} 

Antwort

36

Weil es ein fataler Fehler ist. Verwenden Sie die Funktion class_exists(), um zu überprüfen, ob eine Klasse existiert.

Auch: PHP ist nicht Java - es sei denn, Sie default-Fehler-Handler neu definiert, wird es Fehler auslösen und Ausnahmen nicht auslösen.

+2

ich vergessen , PHP try/get-Funktion hilft Ihnen nur beim Erstellen Ihrer eigenen Ausnahmebehandlung, indem es Ihnen ermöglicht, Ihre eigenen Fehler zu werfen, aber nicht konsequent Fehler wie in C#/Java. –

+1

Siehe http://www.php.net/manual/en/class.errorexception.php zum Beispiel wie man alle (außer fatalen) Fehler in Ausnahmen umschreibt. Wie bereits erwähnt, möchten Sie ab Version 5.3 den Autoloader verwenden, um eine Ausnahme auszulösen, wenn eine Datei mit der angegebenen Klasse nicht gefunden wird. – Mchl

+2

@Edward - es lässt Sie sicher * Ausnahmen * fangen, aber fast alles native in PHP wirft keine Ausnahmen, nur Fehler. Sie können dies leicht umgehen, indem Sie Ihren eigenen * error_handler * definieren und Exceptions mit ErrorException auslösen (siehe http://au.php.net/errorexception und das Beispiel dort). Dies verwandelt das native Fehlersystem von PHP leicht in ein nützliches Exception-basiertes System, das ganz gut mit throw/try/catch usw. funktioniert. –

5

Sie müssen class_exists verwenden, um zu sehen, ob die Klasse existiert, bevor Sie versuchen und instanziieren.

Wenn Sie einen Klassen-Autoloader verwenden, stellen Sie sicher, dass das zweite arg auf true gesetzt ist.

0

Da php einen schwerwiegenden Fehler ausgibt, wenn Sie ein neues Objekt einer nicht existierenden Klasse erstellen. Damit es funktioniert, benötigen Sie die Funktion php> = 5.3 und autoload, in der Sie versuchen sollten, nach einer Datei mit Klassendefinition zu suchen oder Ihre benutzerdefinierte Ausnahme zu werfen.

+0

a) Autoload ist der falsche Weg - siehe http: //au.php.net/manual/en/function.spl-autoload-register.php und b) es benötigt kein PHP 5.3 –

+1

Das Auslösen von Ausnahmen im Autoloader erfordert tatsächlich 5.3. Und es gibt nichts "falsches" daran, solange Sie wissen, was Sie tun (d. H. Es ist ein bisschen albern, eine Ausnahme auszulösen, wenn sich mehr Autoloader in der Autoload-Warteschlange befinden). – Mchl

+0

@El Yobo - Können Sie näher erläutern, was mit Autoload nicht stimmt?Die spl-Funktion macht das gleiche, der einzige Unterschied ist, dass Sie mehr Funktionen bereitstellen können, um nach der richtigen Datei zu suchen. Ans wie für b), wie Mchl sagte, benötigen Sie immer noch php 5.3, damit es eine Ausnahme auslöst. –

10

Alte Frage, aber in PHP7 ist dies eine abfangbare Ausnahme. Obwohl ich immer noch denke, class_exists($class) ist ein expliziter Weg, es zu tun. Sie können jedoch einen try/catch-Block mit dem neuen \Throwable Ausnahmetyp tun:

$className = 'SmartForm' . $smartFormIdCode; 
try { 
    return new $className($smartFormIdCode); 
} catch (\Throwable $ex) { 
    return new SmartFormNull($smartformIdCode); 
} 
+1

Wenn Sie genauer bestimmen möchten, was Sie abfangen, können Sie stattdessen den \ Error-Typ abfangen (getestet für die Arbeit in PHP 7.1). Dies würde Ihren Code spröder für Änderungen in der PHP-Sprache machen, aber auch weniger wahrscheinlich, etwas zu fangen, das Sie nicht vorhaben, es einzufangen. Wenn Sie gute automatisierte Tests haben, sollten Sie in der Lage sein, mit der spezifischeren Version durchzukommen, weil Ihre Tests fehlschlagen würden, wenn PHP plötzlich einen anderen Typ dafür werfen würde. –

0

PHP> = 7.0

php kann fangen 'Klasse nicht gefunden', wie Throwable

try { 
     return new $className($smartFormIdCode); 
} catch (\Throwable $ex) { 
     return new SmartFormNull($smartformIdCode); 
} 
Verwandte Themen