Aufruf einer Klassenmethode: Fehlermeldung
.nils
- php
Hallo,
Ich habe ein Php-File, das eine Funktion einer Klasse aus einer anderen Datei aufruft.
Hier die aufrufende php-Datei:
<?php
/*
* Created on 26.06.2006
* Author: Nils
*/
require_once ("../Bibliotheken/datei.inc.php");
$d=new Datei("C:/testverzeichnis/txt");
echo $d->lies_in_string("test.txt");
?>
Und hier die Klasse:
<?php
/*
* Created on 26.06.2006
* Author: Nils
*/
class Datei
{
var $arbeitsverzeichnis;
function Datei($arbeitsverzeichnis=".") {
$this->setAV($arbeitsverzeichnis) or die("Konnte Funktion setAV() nicht aufrufen");
}
function setAV($arbeitsverzeichnis) {
$this->arbeitsverzeichnis = $arbeitsverzeichnis or die("Konnte Arbeitsverzeichnis nicht auf $arbeitsverzeichnis setzen");
}
function getAV() {
return ($this->arbeitsverzeichnis) or die("Konnte auf die Eigenschaft Arbeitsverzeichnis nicht zugreifen");
}
function lies_in_string($datei) {
$av = getcwd();
chdir($this->arbeitsverzeichnis);
$fp = fopen($datei, "r");
$fc = fread($fp, filesize($datei));
fclose($fp);
chdir($av);
return $fc;
}
}
?>
Mein Problem: wenn ich das so aufrufe, stirbt das Script mit der ersten Fehlermeldung ("Konnte Funktion setAV() nicht aufrufen").
Wenn ich das aus der Klasse rausnehme ( or die("Konnte Funktion setAV() nicht aufrufen")) funktioniert das Script (Es gibt den Inhalt der Datei test.txt im Browser aus). Wieso hängt sich das Script auf ?
Gruß, Nils
Hi,
Wenn ich das aus der Klasse rausnehme ( or die("Konnte Funktion setAV() nicht aufrufen")) funktioniert das Script (Es gibt den Inhalt der Datei test.txt im Browser aus). Wieso hängt sich das Script auf ?
es reagiert völlig korrekt auf die (im Boole'schen Sinne) unwahre Rückgabe der Methode setAV().
Cheatah
Hallo Cheatah,
es reagiert völlig korrekt auf die (im Boole'schen Sinne) unwahre Rückgabe der Methode setAV().
also gibt die Funktion standardmäßig false zurück, wenn ich kein return definiere? Ich hätte jetzt gedacht, sie gibt true zurück...
Gruß, Nils
Hi,
es reagiert völlig korrekt auf die (im Boole'schen Sinne) unwahre Rückgabe der Methode setAV().
also gibt die Funktion standardmäßig false zurück, wenn ich kein return definiere?
das "also" impliziert eine Schlussfolgerung, die ich nicht verstehe. Warum meinst Du, die Rückgabe der Funktion sei false?
Ich hätte jetzt gedacht, sie gibt true zurück...
Und wie bist Du hierauf gekommen?
Cheatah
Hallo Cheatah,
Jetzt bin ich verwirrt...Du hast doch gesagt, die Methode setAV() gibt einen im boolschen Sinne unwahren Wert zurück... das bedeutet doch, sie gibt false zurück, oder?
Gruß, Nils
Hallo Cheatah,
Ich glaub, ich versteh, was Du meinst: die Methode gibt nichts zurück, und das wirkt so, als wenn Sie false zurückgeben würde. Meinst Du das ?
Gruß, Nils
Hi,
Jetzt bin ich verwirrt...Du hast doch gesagt, die Methode setAV() gibt einen im boolschen Sinne unwahren Wert zurück... das bedeutet doch, sie gibt false zurück, oder?
false ist _ein_ im Boole'schen Sinne unwahrer Wert, nicht jedoch der einzige. Siehe:
print false ? 'wahr' : 'unwahr';
print '' ? 'wahr' : 'unwahr';
print 0 ? 'wahr' : 'unwahr';
...
Ich glaub, ich versteh, was Du meinst: die Methode gibt nichts zurück,
Nicht raten. Überprüfen.
Cheatah
echo $begrüßung;
Nicht raten. Überprüfen.
var_dump() ist hierfür ein geeignetes Hilfsmittel.
echo "$verabschiedung $name";
Hallo dedlfix,
var_dump() ist hierfür ein geeignetes Hilfsmittel.
Danke, das hab ich gebraucht, ist also NULL, was als false interpretiert wird:
<?php
$x=NULL;
if($x)echo"true";
else echo"false";
//gibt 'false' aus.
?>
Gruß, Nils
Hallo,
Ich nehme jetzt an, da ich es nicht verstehe, die Funktion gibt etwas zurück, was als falsch interpretiert wird.
Habs jetzt so gemacht:
<?php
class Datei
{
var $arbeitsverzeichnis;
function Datei($arbeitsverzeichnis=".") {
$this->setAV($arbeitsverzeichnis) or die("Konnte Funktion setAV() nicht aufrufen");
}
function setAV($arbeitsverzeichnis) {
if ($this->arbeitsverzeichnis = $arbeitsverzeichnis) return true;
else die("Konnte das Arbeitsverzeichnis nicht setzen");
}
function getAV() {
return ($this->arbeitsverzeichnis) or die("Konnte auf die Eigenschaft Arbeitsverzeichnis nicht zugreifen");
}
function lies_in_string($datei) {
$av = getcwd();
chdir($this->arbeitsverzeichnis);
$fp = fopen($datei, "r");
$fc = fread($fp, filesize($datei));
fclose($fp);
chdir($av);
return $fc;
}
}
?>
Gruß, Nils
Moin!
An deiner Klasse ist zu kritisieren, dass du die Fehlerbehandlung wirklich übertreibst - und ohnehin so formuliert hast, wie man sie nur zu Testzwecken formulieren sollte. Eine Klasse sollte NIE das Skript abbrechen, sie sollte das Vorliegen eines bösen Fehlerzustandes immer an das aufrufende Programm zurückmelden, damit dieses dann abbrechen kann - oder auch nicht.
Fangen wir mal "innen" an: Ist es denn wirklich notwendig, das erfolgreiche Zuweisen eines Wertes an eine Eigenschaft der Klasse innerhalb von setAV zu prüfen? Was passiert, wenn man als Arbeitsverzeichnis den Leerstring zuweisen will? Richtig, die Klasse bricht ab!
Wann aber kann eine Zuweisung an eine Eigenschaft der Klasse fehlschlagen? Doch eigentlich nur dann, wenn die Eigenschaft nicht existiert. Dann aber würde sich PHP (mindestens bei error_reporting(E_ALL)) ohnehin mit einer Fehlermeldung melden. Ansonsten kann bei diesem Schritt nichts schiefgehen.
Was natürlich "schiefgehen" kann im Sinne der Klasse, wäre eine falsche Verzeichnisangabe. Aber Prüfungen über die Zulässigkeit des übergebenen Parameters finden in setAV() ja nicht statt, also ist alles zulässig.
Ein Schritt weiter nach außen finden wir im Konstruktor der Klasse den Aufruf von setAV. Hier wird wieder kontrolliert, ob diese Methode erfolgreich aufgerufen werden konnte.
Wann aber kann ein Methodenaufruf fehlschlagen und KEINE PHP-Fehlermeldung nach sich ziehen? Auch an dieser Stelle ist die Fehlerbehandlung vollkommen überflüssig und kann komplett entfallen. Entweder existiert setAV(), dann kann man es auch aufrufen, oder es existiert nicht, bzw. erhält die falsche Anzahl von Parametern - dann meldet sich automatisch PHP, mindestens mit einer NOTICE, bei fatalen Fehlern wird das Skript sogar gestoppt, sofern nicht sogar Parsingfehler den Start komplett verhindern.
Die einzige Methode, die komplexere Funktionen ausführen muß, ist lies_in_string() - aber dort fehlt es komplett an Fehlerbehandlungsmethoden.
Beispiele: War chdir() erfolgreich? War fopen() erfolgreich? War fread() erfolgreich? War fclose() erfolgreich?
Und wie wäre es stattdessen damit, einfach Verzeichnisname und Dateiname zu einem Pfad zusammenzubasteln und dann file_get_contents() aufzurufen?
<?php
function lies_in_string($datei) {
$av = getcwd();
chdir($this->arbeitsverzeichnis);
$fp = fopen($datei, "r");
$fc = fread($fp, filesize($datei));
fclose($fp);
chdir($av);
return $fc;
}
?>
Mit genauso wenig Fehlerbehandlung, wie oben, wäre dieser Code von der Funktion her annähernd identisch:
~~~php
function lies_in_string($datei) {
return file_get_contents($this->arbeitsverzeichnis."/".$datei);
}
- Sven Rautenberg
echo $begrüßung;
In deiner Beschreibung gehst du sicherlich von dem aus, was .nils erreichen wollte. Aber das was stattdessen passiert stimmt teilweise nicht mit deinen Ausführungen überein.
Wann aber kann eine Zuweisung an eine Eigenschaft der Klasse fehlschlagen? Doch eigentlich nur dann, wenn die Eigenschaft nicht existiert. Dann aber würde sich PHP (mindestens bei error_reporting(E_ALL)) ohnehin mit einer Fehlermeldung melden. Ansonsten kann bei diesem Schritt nichts schiefgehen.
Eine Zuweisung an eine Eigenschaft wird immer ausgeführt. Wenn die Eigenschaft bis dahin in der aktuellen Instanz nicht existierte wird sie angelegt. Es gibt dazu auch keine Notice. Diese gibt es nur bei Lesezugriffen auf nicht vorhandene Eigenschaften (bzw. Variablen allgemein).
Was natürlich "schiefgehen" kann im Sinne der Klasse, wäre eine falsche Verzeichnisangabe. Aber Prüfungen über die Zulässigkeit des übergebenen Parameters finden in setAV() ja nicht statt, also ist alles zulässig.
Auch nicht ganz richtig. So lautete die Anweisung:
$this->arbeitsverzeichnis = $arbeitsverzeichnis or die("Konnte Arbeitsverzeichnis nicht auf $arbeitsverzeichnis setzen");
Hier wird nicht geprüft, ob die Zuweisung erfolgreich war. Vielmehr wird zuerst die Zuweisung ausgeführt, da = einen höheren Rang hat. Das Ergebnis einer Zuweisung ist immer der Wert der Zuweisung (rechtes Argument). Die Zuweisung findet also auf jeden Fall statt:
$x = 42;
$x = 0 or die("x = $x");
Das ergibt die Ausschrift: x = 0
Nun kommt der Operator "or" zur Anwendung. Ist das Ergebnis dieser Zuweisung (oder allgemeiner gesagt: ist der Audruck links vom "or" oder speziell hier: ist der Inhalt von $this->arbeitsverzeichnis nach der erfolgten Zuweisung) ein Wert, der als false interpretiert wird, kommt der Ausdruck rechts von "or" zur Ausführung. Ergibt die Zuweisung etwas, das als true interpretiert wird, ist das Ergebnis des "or"-Operators bereits eindeutig und der Ausdruck rechts davon kommt aufgrund des Kurzschlussverfahrens nicht mehr zur Ausführung.
Der Abbruch erfolgt also nur in den Fällen, in denen $arbeitsverzeichnis einen der an der verlinkten Stelle aufgeführten Werte enthält.
Ein Schritt weiter nach außen finden wir im Konstruktor der Klasse den Aufruf von setAV. Hier wird wieder kontrolliert, ob diese Methode erfolgreich aufgerufen werden konnte.
Nein, hier wird der Rückgabewert der Methode setAV() ausgewertet, der, weil nichts anderes mittels einer return-Anweisung festgelegt wurde, null ist.
function lies_in_string($datei) {
return file_get_contents($this->arbeitsverzeichnis."/".$datei);
}
$this->arbeitsverzeichnis könnte man noch mit rtrim($this->arbeitsverzeichnis, '/') und $datei mit dem ltrim-Pendant dazu behandeln, damit man nicht zu viele Verzeichnistrenner zwischen beiden hat. (Dies kann passieren, wenn jemand (außenstehendes) die Konfigurationswerte ändert und nicht darauf achtet, dass kein / am Ende bzw. Anfang angefügt werden darf.)
echo "$verabschiedung $name";