Try-Catch funktioniert nicht beim Instanzieren?
OneWorld
- php
try
{
$instance = new class_xyz();
}
catch (Exception $e)
{
echo "Klasse wurde noch nicht implementiert.";
}
Warum wird das nicht abgefangen, wenn die Klasse nicht verfügbar ist? Meine Fehlermeldung aus dem catch-Block wird nicht angezeigt.
Stattdessen wird folgendes ausgegeben:
Fatal error: Class 'class_xyz' not found in C:\Program Files\Zend\Apache2\htdocs\controllers\Ma… on line 227
Ich nutze außerdem __autoload. Dieses prüft das Vorhandensein des Klassenfiles und included es dann. Deswg. brauch ich für das Instanzieren ein try catch.
function __autoload( $class_name )
{
if (file_exists('controllers/classes/' . $class_name . '.class.php'))
{
require_once 'controllers/classes/' . $class_name . '.class.php';
return true;
}
return false;
}
Hi!
Warum wird das nicht abgefangen, wenn die Klasse nicht verfügbar ist? Meine Fehlermeldung aus dem catch-Block wird nicht angezeigt.
In try-catch können nur Exceptions abgefangen werden. Eine PHP-Fehlermeldung ist jedoch keine solche.
Ich nutze außerdem __autoload. Dieses prüft das Vorhandensein des Klassenfiles und included es dann. Deswg. brauch ich für das Instanzieren ein try catch.
Siehe http://de.php.net/manual/en/language.oop5.autoload.php
Lo!
Hi.
try
{
$instance = new class_xyz();
}
catch (Exception $e)
{
echo "Klasse wurde noch nicht implementiert.";
}
>
> Warum wird das nicht abgefangen, wenn die Klasse nicht verfügbar ist?
Weil keine Exception geworfen wird, die abgefangen werden könnte.
> Ich nutze außerdem \_\_autoload. Dieses prüft das Vorhandensein des Klassenfiles und included es dann.
Oder sie prüft das Vorhandensein des Klassenfiles und gibt brav und stillschweigend false zurück, ohne einen Piep zu sagen, wenn die Datei nicht verfügbar ist.
> ~~~php
function __autoload( $class_name )
> {
> if (file_exists('controllers/classes/' . $class_name . '.class.php'))
> {
> require_once 'controllers/classes/' . $class_name . '.class.php';
> return true;
> }
> return false;
> }
1.: Achtung tocttou - es ist selten ratsam, ein File zu einem anderen Zeitpunkt als dem seines Benutzens auf Existenz zu prüfen und sich dann darauf zu verlassen.
2.: Du wirfst keine Exception, wenn das File fehlt. Und das ist höchstwahrscheinlich auch richtig so. Exceptions sind Ereignisse, die im Programmablauf vorgesehen sind und kontrolliert innerhalb der Programmlogik behandelt werden. Wenn ein File fehlt, dann ist dies wahrscheinlich nicht der Fall, sondern Du willst einen Fehler erzeugen. Falls Du wirklich eine Exception willst, dann sei die Frage gestattet, was das Programm in dem Fall tun soll, wenn die Klasse nicht gefunden wird (außer dieses dem Benutzer mitzuteilen).
Einen Fehler hingegen würde die Funktion require_once automatisch für Dich erzeugen, wenn Du sie denn einfach ließest.
Viele Grüße,
der Bademeister
Moin!
try
{
$instance = new class_xyz();
}
catch (Exception $e)
{
echo "Klasse wurde noch nicht implementiert.";
}
>
> Ich nutze außerdem \_\_autoload. Dieses prüft das Vorhandensein des Klassenfiles und included es dann. Deswg. brauch ich für das Instanzieren ein try catch.
Nein, brauchst du absolut nicht.
Wenn dein Autoloader eine Klasse nicht finden kann, und deshalb ein Objekt nicht instanziiert werden kann, dann ist das ein extrem heftiger Fehler, der zu Recht mit dem Programmabbruch geahndet wird.
Autoloading sorgt, wenn es funktioniert, automatisch dafür, dass alle die angeforderten Klassen includiert und verfügbar sind, wenn sie benötigt werden. Dafür ist im instanziierenden Code keinerlei Fehlerbehandlung durch Abfangen von Exceptions notwendig.
Denn viel spannender ist ja, was nach deinem Code passiert! Du hast $instance, und darin wäre jetzt KEIN Objekt der Klasse class\_xyz. Deine Exception wäre geworfen, der Code läuft aber weiter. Irgendwann wirst du zwangsläufig $instance benutzen wollen - und zwar so, als wäre darin eine Klasse class\_xyz drin, was aber nicht der Fall ist. Dieses Problem müsstest du aber dann erneut behandeln... das Ergebnis ist, dass du in deinen Code so viel Fehlerbehandlung eintragen musst, dass es einfacher ist, wenn du einfach eine Datei anlegst, die dein Autoloader durch Benutzen der Klasse "class\_xyz" einbindest, und dorthinein die Dummy-Zeile schreibst
~~~php
<?php
echo "Klasse class_xyz wurde noch nicht implementiert.";
Und deine Instanziierung ist dann ganz normal:
$instance = new class_xyz();
Der Effekt ist fast derselbe.
- Sven Rautenberg