| PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Post your PHP questions here! |
 |
|

28-05-2009, 02:40
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Zitat:
Zitat von phpMorpheus2
Ich kann jedoch nicht mehrere Exceptions in einem Durchlauf definieren und catch'n !?
|
Doch, das kannst du. Erweitern wir das Beispiel von oben:
PHP-Code:
function inverse($x) { if ($x == 0) throw new InvalidArgumentException('Division durch Null!'); if ($x == 1) throw new DontWasteMyTimeException($x.' ist neutral bzgl. Multiplikation'); return 1/$x; }
try { echo '1/0 = ' . inverse(0); } catch (InvalidArgumentException $e) { echo $e->getMessage() . ' ' . $e->getArg(); } catch (DontWasteMyTimeException $e) { echo 'Es ist ein Fehler aufgetreten: ' . $e->getMessage(); }
Richtig interessant wird es, wenn man dem Beispiel folgendes hinzufügt:
PHP-Code:
// Das Beispiel ist nicht ganz korrekt und auch nicht besonders sinnvoll.
function negative($x) { if (abs($x) == 0) throw new DontWasteMyTimeException($x.' ist neutral bzgl. Addition'); return -1 * $x; }
function negativeInverse($x) { if (abs($x) == 0) throw new DontWasteMyTimeException($x.' ist neutral bzgl. Addition'); return -1 * inverse($x); }
try { echo '-(1/0) = ' . negative(inverse(0)); echo '-(1/0) = ' . negativeInverse(0); } catch (InvalidArgumentException $e) { echo $e->getMessage() . ' ' . $e->getArg(); } catch (DontWasteMyTimeException $e) { echo 'Es ist ein Fehler aufgetreten: ' . $e->getMessage(); }
Jetzt bubbelt eine Exception von inverse() nach oben bis sie gefangen wird. Um das mit deinem $arr hinzubekommen, musst du in jeder Funktion unheimlich viel Logik implementieren. Oder du beschränkst dich auf "flache Calls", d.h. eine Funktion darf keine andere Funktion aufrufen.
Exceptions sind ein Mittel der Sprache und dadurch viel mächtiger und eleganter als alles was du mit deinem $arr erreichen kannst.
Ich habe übrigens auch schon Applikationen gesehen, die bei der Formularvalidierung für jede fehlgeschlagene Prüfung eine Exception geworfen haben. Man kann die alle in einem Container sammeln und dann dem User die ganze Latte von Fehlermeldungen anzeigen. Aber dafür sind Exceptions nun auch wieder nicht gemacht. Sie unterbrechen den Programmfluss und das sollte, wie der Name schon sagt, nur in Ausnahmefällen passieren.
Geändert von onemorenerd (28-05-2009 um 02:44 Uhr)
|

28-05-2009, 15:28
|
|
phpMorpheus2
Registrierter Benutzer
|
|
Registriert seit: Apr 2007
Beiträge: 646
|
|
Das hört sich ja sehr schick an.
Eine rellativ einfache und dazu noch einmal global definierte klasse zur Fehlermeldungsausgabe...
Der Code läuft nach dem Catch'n ganz normal weiter wie ich ausprobiert habe.
Das könnte ein sehr hilfreicher Ansatz sein.
Aber jetzt alles umbasteln auf Exceptions... 
Aber es lohnt sich, solange man noch im Aufbau ist.
Also dann probier ich mal die Exceptions zu impl.
Danke Leute.
|

28-05-2009, 15:40
|
|
phpMorpheus2
Registrierter Benutzer
|
|
Registriert seit: Apr 2007
Beiträge: 646
|
|
JEDOCH!, muss ich bei jeder Abfrage, welche bei einem Fehler die Exception wirft, die Exception selbst design!
Sprich, ich habe keine Möglichkeit, die Klasse so zu definieren,
dass z.B. immer eine vordefinierte Tabelle mit angepassten Eigenschaften etc.
und der beinhalteten Fehlermeldung ausgegeben wird.
Ich muss bei jeder geworfenen Exception neu definieren.
Das ist wiederum auch blöd.
Oder kann ich eine Exception so definieren,
dass bei einem gewissen Fehler eine zugeordnete Exception geworfen wird,
welche bei Ausgabe (getMsg) das design beibehält, welches in der Klasse definiert wird?
Geht das?
|

28-05-2009, 15:48
|
|
combie
PHP Expert
|
|
Registriert seit: May 2006
Beiträge: 2.925
|
|
Zitat:
Oder kann ich eine Exception so definieren,
dass bei einem gewissen Fehler eine zugeordnete Exception geworfen wird,
welche bei Ausgabe (getMsg) das design beibehält, welches in der Klasse definiert wird?
|
Exceptions haben kein Design!
Das ist Aufgabe der View.
Und sicherlich!
Du kannst dir selber eigene Exceptions basteln.
Und ja! Es ist auch völlig üblich, das zu tun.
Mein Tipp:
Bringe erstmal dein konkretes Projekt zum Abschluß.
Zwischenzeitlich:
1. Liest du das Handbuch PHP: Klassen und Objekte (PHP 5) - Manual
2. Peters Seiten (die Links hast du schon bekommen)
3. kaufst dir ein Buch. Z.B. php oop design pattern
Vermutlich arbeitest du schon seit Jahren prozedural. Das hat den Vorteil, dass du nicht mehr so viele Grundlagen lernen mußt. Ca. 1 Jahr lernen gespart. Allerdings dürte sich das Prozedurale, bei dir, recht fest gefressen haben. Die Umstellung wird also schwieriger. Statt 6 Monate lernen, jetzt ca 1 Jahr.
Ein Vorgeschmack:
Hier mal ein primitives Beispiel, wie man die rekursive Auflistung eines Verzeichnisses incl. Blätterfunktion OOPartig erledigen könnte.
PHP-Code:
<?php
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', TRUE);
// ------------------
// Einstellungen
$such_in = '.'; // Verzeichnis, welches durchsucht werden soll
$pro_seite = 10; // Anzahl Einträge pro Seite
// Pager , Blätterfunktion
$seite = max(0,empty($_GET['S'])?0:(int)$_GET['S']);
$offset = $seite*$pro_seite;
// Rekursivgedöns
$dir = new LimitIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($such_in)),$offset,$pro_seite);
// Ausgabe
?>
<h1>Seite: <?php echo $seite ?> </h1>
<a href="?S=<?php echo ($seite-1)?>">Prev</a> ||
<a href="?S=<?php echo ($seite+1)?>">Next</a>
<hr>
<?php
$dir->rewind();
if($dir->valid())
foreach($dir as $datei)
echo $datei->getPathname()."<br>";
else echo 'Hier ist Ende!<br>';
Geändert von combie (28-05-2009 um 15:53 Uhr)
|

28-05-2009, 16:07
|
|
phpMorpheus2
Registrierter Benutzer
|
|
Registriert seit: Apr 2007
Beiträge: 646
|
|
Danke für die Beispiele.
Die helfen mir enorm weiter!
Eine Frage.
Wenn ich eine Try-Catch abfrage habe, in welcher sich noch eine Try-Catch abfrage befindet, was passiert, wenn die zweite Try-Catch abfrage eine Exception wirft?
Wird in der ersten Try-Catch abfrage sofort in die Catch gegangen, oder wird die erste Try-Catch abfrage trotz der von Ihr beinhalteten Try-Catch funktion, welche ja die Exception wirft, weitergeführt?
Hoffe man versteht was ich meine.
Sonst bastel ich ein Beispiel.
Danke
|

28-05-2009, 16:10
|
|
combie
PHP Expert
|
|
Registriert seit: May 2006
Beiträge: 2.925
|
|
Du kannst try und catch Blöcke schachteln.
Das sieht aber weder schön aus, noch ist es sonderlich übersichtlich.
 Da kommt deine prozedurale Denke wieder zum Vorschein.
Frage:
Warum liest du nicht erst das Handbuch zu dem Thema?
Da steht doch genau die Antwort: PHP: Ausnahmebehandlung - Manual
|

28-05-2009, 19:40
|
|
phpMorpheus2
Registrierter Benutzer
|
|
Registriert seit: Apr 2007
Beiträge: 646
|
|
Ich hatte mir dann in etwa solch einen Aufbau gedacht:
(Ich bitte um Eure Meinung)
PHP-Code:
<?php
function FehlerausgabeMitDesign($err)
{
//Hier kann ich das Auftreten einer Exception
//meinen Ansprüchen nach gestalten und ausgeben.
//So sehen alle Fehlermeldung, ausgenommen von den jeweiligen
//Fehlermeldungen, einheitlich aus.
//So muss nicht in jedem "catch" das Design wieder und wieder
//neu modelliert werden.
echo "<font color=red>$err</font>";
}
function Validierung($x) {
if ($x == 0) {
throw new Exception('Der Wert ist 0');
}
else return "Wert ist <> 0";
}
function AllgemeineFunktion($x) {
Validierung($x);
echo "Ich werde ausgegeben, wenn kein Exception vorliegt<br>
Der Wert ist $x";
}
try {
echo AllgemeineFunktion(0); //etc1(0) Exception
//etc1(*) Fortführung
} catch (Exception $e) {
FehlerausgabeMitDesign($e->getMessage());
}
// Ausführung fortsetzen
echo '<br>Und weiter gehts mit dem Code falls gewollt...';
?>
|

28-05-2009, 20:50
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Naach, das ist doch Kraut und Rüben Code. Von der Validierung() erwartet man true oder false. Aber du wirfst eine Exception oder gibst einen String zurück, den niemand entgegen nimmt.
Scheinbar haben dich die Beispiele weiter oben eher verwirrt als erleuchtet. Exceptions treten auf, wenn im Programmablauf eine Ausnahmebedingung eintritt, mit der man irgendwie umgehen kann.
|

28-05-2009, 21:09
|
Kropff
  Administrator
|
|
Registriert seit: Mar 2002
Ort: Köln
Beiträge: 11.308
|
|
Zitat:
|
Naach, das ist doch Kraut und Rüben Code
|
OffTopic: Sei nicht so streng mit ihm, er übt ja noch
peter
__________________
Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
Meine Seite
|

29-05-2009, 00:53
|
|
phpMorpheus2
Registrierter Benutzer
|
|
Registriert seit: Apr 2007
Beiträge: 646
|
|
Zitat:
Zitat von onemorenerd
Naach, das ist doch Kraut und Rüben Code. Von der Validierung() erwartet man true oder false. Aber du wirfst eine Exception oder gibst einen String zurück, den niemand entgegen nimmt.
Scheinbar haben dich die Beispiele weiter oben eher verwirrt als erleuchtet. Exceptions treten auf, wenn im Programmablauf eine Ausnahmebedingung eintritt, mit der man irgendwie umgehen kann.
|
Sind Exceptions jetzt nur für "Ausnahmefehler" geeignet, oder auch für allgemeine true/false abfragen?
Weil ansonsten kommt es aufs selbe raus, wie ich programmiere bislang.
Eine Funktion ruft die nächste auf und bekommt true/false raus (err und msg)
...
Also Exceptions NICHT nutzen für gewöhnliche true/false rückgabewerte?!
|

29-05-2009, 01:10
|
|
phpMorpheus2
Registrierter Benutzer
|
|
Registriert seit: Apr 2007
Beiträge: 646
|
|
Euren Beispielen zu folge würde ich die Exception Methode nun dazu missbrauchen:
PHP-Code:
<?php
function check_id($id) { if($id != 0) { return true; } else { throw new Exception('ID falsch'); } }
function check_size($size) { if($size != 0) { return true; } else { throw new Exception('Size falsch'); } }
try { check_id(23424); check_size(183); echo "Es gab kein Exception"; //Alles was weiterhin kommt, kann sicher davon ausgehen, //dass check_id() und check_size() true sind. } catch (Exception $e){ echo $e->getMessage(); }
?>
Geändert von phpMorpheus2 (29-05-2009 um 01:14 Uhr)
|

29-05-2009, 02:20
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Nur für Ausnahmefehler. Eine Funktion, die eine ID prüfen soll, gibt von Natur aus true oder false zurück. Entweder ist die ID valide oder nicht.
Eine Exception sollte diese Funktion nur werfen, wenn sie ihre Prüfung gar nicht durchführen kann. In dieser Hinsicht waren die obigen Beispiele irreführend. Verzeihung. Ich bohre deine ID- Prüfung mal etwas auf, um es zu verdeutlichen:
PHP-Code:
// prüft ob eine ID in DB existiert function check_id($id) { $result = db_result(db_query('SELECT COUNT(*) FROM data WHERE id = ' . $id)); if (!is_numeric($result)) { // $result könnte false oder null sein throw new DatabaseException('Could not query for ID', $result); } return (bool) $result; }
Die Exception wird geworfen, wenn die Funktion ihren eigentlichen Zweck nicht erfüllen kann. Der Grund für die Ausnahme liegt woanders und die Funktion kann sich nicht selbst aus der Patsche helfen. Sie weiß aber auch nicht, ob der Code, der sie aufrief eventuell ohne ihr Ergebnis weitermachen kann. Wäre ja zumindest denkbar. Deshalb kein die() sondern eine Exception.
Aber vorsicht: Dieses Beispiel ist auch wieder ungeeignet. Denn eigentlich sollte db_query() die Exception werfen, wenn es die DB nicht erreichen kann. Nur hätte ich dann den vorherigen Absatz nicht so schreiben können.
|

29-05-2009, 12:49
|
|
phpMorpheus2
Registrierter Benutzer
|
|
Registriert seit: Apr 2007
Beiträge: 646
|
|
Aha!
Also sind Exceptions doch nur für Ausnahmefehler geeignet.
Gut.
Das hat dann aber nichts mit meinen schönen verschachtelungen zutun.
Ich muss also dennoch die Werte err/msg übergeben, falls ein false wert
auftritt.
Die Methode mit dem Exception würde "dennoch" die Validierung sehr erleichtern,
wenn man es so nutzen würde wie in meinem letzten Beispiel.
Warum darf ich dort keine Exception als "falsewert Rückgabe" nutzen?
So Spare ich mir viele Abfragen und rumgedönse...
|

29-05-2009, 12:53
|
|
PHP-Desaster
PHP Expert
|
|
Registriert seit: Mar 2006
Beiträge: 3.104
|
|
Guck dir doch mal die Lösung von Zend_Validate an. Da kannst du dir sicher etwas abschauen.
|

29-05-2009, 14:29
|
 |
onemorenerd
 Moderator
|
|
Registriert seit: Mar 2005
Ort: Berlin
Beiträge: 9.481
|
|
Ich habe weiter oben was von "anderen Kanälen" gesagt. Exceptions sind ein Beispiel dafür, aber du kannst dir bei Bedarf auch eigene Kanäle schaffen.
PHP-Code:
// prüft ob eine ID in DB existiert function check_id($id) { if ($id == 0) { AppErrorCollection::addErrorMessage('Bitte keine Nullen verwenden'); }
$result = db_result(db_query('SELECT COUNT(*) FROM data WHERE id = ' . $id)); if (!is_numeric($result)) { // $result könnte false oder null sein throw new DatabaseException('Could not query for ID', $result); } return (bool) $result; }
// irgendwo im View folgt dann AppErrorCollection::printErrorMessages();
Das ist jetzt schon wieder ein nicht wirklich gelungenes Beispiel (AppErrorCollection statisch), aber es kommt deiner prozeduralen Denke näher.
Geändert von onemorenerd (29-05-2009 um 14:31 Uhr)
|
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
|
| Themen-Optionen |
|
|
| Thema bewerten |
|
|
Forumregeln
|
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.
HTML-Code ist aus.
|
|
|
|
PHP News
|