Verbesserungsvorschläge für eine File-Klasse

Puh...das hört sich nach viel Arbeit an...wird sich aber bestimmt lohnen! Mal sehen wie ich in nächster Zeit dazu komme! Aber ich werde auf jeden Fall dranbleiben!
Danke nochmal! Falls euch/dir ;-] noch was einfällt bitte bescheid sagen!

greetz
daddz
 
Also...ich hab jetzt noch einige Dinge verändert die in der "Vorgänger-Version" nicht richtig funktioniert haben! (z.B. die error funktion) Gibt es jetzt noch etwas was ich verändern sollte/besser machen sollte? Wenn nicht könnt ich die in die Klasse noch Kommentare reinschreiben und das ganze schön hergemacht in Die Tutorials Inbox "werfen"! ;-] So als Codeschnipsel...

Hier der Code:
PHP:
<?php
class my_file {
	protected $ferr;
	protected $fbuffer;
	private $fname;
	public $fmode;
	public $fvalue;
	public $fchmod;
			
	function my_file($filename) {
		$this->fname = $filename;
		$this->ferr = "errorcodes.txt";
		$this->fbuffer = "";
		$this->fmode = "w";
		$this->fvalue = "";
	}
	
	function my_file_create() {
		if(file_exists($this->fname)) {
			$this->my_file_error(1);
			return false;
		}
		else {
			$file = fopen("".$this->fname."", "w");
			fclose($file);
			if(file_exists($this->fname)) {
			    return true;
			}
			else {
				$this->my_file_error(2);
				return false;
			}
		}
	}
	
	function my_file_read() {
		if(!file_exists($this->fname)) {
			$this->my_file_error(4);
			return false;
		}
		else {
			$file = fopen("".$this->fname."", "r");
			if($file) {
				while(!feof($file)) {
					$index[] = fgets($file, 128);
				}
				return $index;
			}
			else {
				$this->my_file_error(3);
				return false;
			}
		}
	}
	
	function my_file_write() {
		if(!file_exists($this->fname)) {
			$this->my_file_error(4);
			return false;
		}
		
		else {
			$file = fopen("".$this->fname."", "".$this->fmode."");
			if($file) {
				fwrite($file, $this->fvalue);
				return true;
			}
			else {
				$this->my_file_error(3);
				return false;
			}
		}
		
	}
	
	private function my_file_error($errorcode) {
		$this->fbuffer = $this->fname;
		$this->fname = $this->ferr;
		$errmsg = $this->my_file_read();
		$err = $errorcode - 1;
		echo $errmsg[$err];
		$this->fname = $this->fbuffer;
		exit;
	}
	
	function my_file_setRights() {
		chmod($this-fn, $this->fchmod);
		return true;
	}
}
?>

Danke schonmal!

greetz
daddz
 
Na, dann will ich noch mal nörgeln :D
Keine Sorge, es geht nur noch um Bezeichnungen.
Die Bezeichnung my_irgendwas ist mir bisher nur in zwei Fällen untergekommen. Zum einen bei der Bezeichnung einer Subklasse in Übungen oder als Objektbezeichner einer bestimmten Klasse "Irgendwas".
Ein anderer Name ist für eine finale Version vielleicht sinnvoll. Mir ist klar, dass file auch eine PHP-Funktion ist. Wenn PHP das mitmacht, eine Klasse, wie eine vorhandene Funktion zu benennen (bei Java geht sowas), halte ich es für sinnvoll, die Klasse so zu nennen oder etwas in den Namen zu bringen, was kennzeichnet, dass die Klasse von Dir ist (z.B. DaddzFile) oder File mit irgendeinem Zusatz (z.B. FileHandler, auch wenn das Beispiel evtl. etwas irre führt).
Den Klassennamen musst Du in den Funktionen nicht wiederhohlen, da diese ohnehin über die Klasse angesprochen werden.
Ich persönlich halte mich an die Konvention, die ich von Java her kenne.
D.h. Klassennamen beginnen mit einem Großbuchstaben, werden klein fortgesetzt und jedes neue Wort innerhalb des Namens wird mit einem Großbuchstaben begonnen, es werden keine Unterstriche verwendet [FileHandler, DaddzFile].
Methoden- und Variablennamen beginnen mit einem Kleinbuchstaben und werden klein fortgesetzt und neue Wörter innerhalb des Namens beginnen mit einem Großbuchstaben, es werden keine Unterstriche verwendet [fMode, setRights()]. Dies gilt nicht für den Konstruktor, dieser wird genau so, wie die Klasse, geschrieben.
Konstanten werden ausschließlich groß geschrieben, Wörter innerhalb des Bezeichners können mit Unterstrich getrennt werden [MEINE_KONSTANTE].
Ich bin mir nicht sicher, wie die Konventionen in PHP aussehen, aber auch hier würde ich keine Variablen public machen, sondern über getter und setter drauf zugreifen [getMode() und setMode($mode)]. Dann könntest Du in dem entsprechenden setter auch gleich die Datei zum Beispiel im entsprechenden Modus öffnen (und ggf. vorher schließen).

Wie gesagt, keiner muss sich an irgendwelche Konventionen halten und diese sind für Java, evtl. gelten für PHP andere allgemein übliche Regeln.

Gruß hpvw
 
So...ich hab jetzt mal deine doch sehr sinnvollen Nörgeleien umgesetzt! ;-]
Hoffe so ist es besser aber was hast du damit gemeint:
Dann könntest Du in dem entsprechenden setter auch gleich die Datei zum Beispiel im entsprechenden Modus öffnen (und ggf. vorher schließen).
Wie soll ich mir das vorstellen?

Hier der Code...zum x-ten mal :rolleyes:
PHP:
<?php
class DaddzFile {
	protected $fErr;
	protected $fbuffer;
	private $fName;
	private $fMode;
	private $fValue;
	private $fChmod;
			
	function DaddzFile($filename) {
		$this->fName = $filename;
		$this->fErr = "errorcodes.txt";
		$this->fbuffer = "";
		$this->fMode = "w";
		$this->fValue = "";
	}
	
	function Create() {
		if(file_exists($this->fName)) {
			$this->Error(1);
			return false;
		}
		else {
			$file = fopen("".$this->fName."", "w");
			fclose($file);
			if(file_exists($this->fName)) {
			    return true;
			}
			else {
				$this->Error(2);
				return false;
			}
		}
	}
	
	function Read() {
		if(!file_exists($this->fName)) {
			$this->Error(4);
			return false;
		}
		else {
			$fFile = fopen("".$this->fName."", "r");
			if($fFile) {
				while(!feof($fFile)) {
					$fIndex[] = fgets($fFile, 128);
				}
				return $fIndex;
			}
			else {
				$this->Error(3);
				return false;
			}
		}
	}
	
	function Write() {
		if(!file_exists($this->fName)) {
			$this->Error(4);
			return false;
		}
		
		else {
			$file = fopen("".$this->fName."", "".$this->fMode."");
			if($file) {
				fwrite($file, $this->fValue);
				return true;
			}
			else {
				$this->Error(3);
				return false;
			}
		}
		
	}
	
	private function Error($eErrorcode) {
		$this->fBuffer = $this->fName;
		$this->fName = $this->fErr;
		$fErrmsg = $this->Read();
		$fError = $eErrorcode - 1;
		echo $fErrmsg[$fError];
		$this->fName = $this->fBuffer;
		unset($eErrorcode);
		exit;
	}
	
	function SetRights() {
		chmod($this-fName, $this->fChmod);
		return true;
	}
	
	function SetFileMode($eMode) {
		unset($this->fMode);
		$this->fMode = $eMode;
		unset($eMode);
	}
	
	function GetFileMode() {
		return $this->fMode;
	}
	
	function SetWriteValue($eValue) {
		unset($this->fValue);
		$this->fValue = $eValue;
		unset($eValue);
	}
	
	function GetWriteValue() {
		return $this->fValue;
	}
	
	function SetChmodMode($eMode) {
		unset($this->fChmod);
		$this->fChmod = $eMode;
		unset($eMode);
	}
	
	function GetChmodMode() {
		return $this->fChmod;
	}
}

?>

Hab etz lauter "getter" und "setter" reingesetzt und die ganzen Variablen schön umbenannt.
Danke das du so aktiv mithilfst! ;-]

greetz
daddz
 
Also private bewirkt, das man nicht von außerhalb der Klasse die Variable verändern kann!
Das geht z.B nicht:
PHP:
$class->$variableDiePrivateIst = 1;
Man kann sie auch nicht aus einer abgeleiteten Klasse verändern!

Bei Protected ist es genau das gleiche nur das man Protected aus einer abgeleiteten Klasse verändern kann!

greetz
daddz
 
In Deinem Code ist es vielleicht ratsam, nur lesenden Zugriff auf einige Attribute zuzulassen. Das ist es, wozu sich getter und setter in Verbindung mit privaten Attributen eignen.
Zum Beipiel wird bei Dir der "fMode" gar nicht verwendet und bräuchte somit keinen Setter. Man könnte ihn aber in read() und write() [Hinweis: Methoden klein beginnen] setzen und der Nutzer der Klasse hätte über den getter einen Hinweis darauf, was als letztes mit der Datei gemacht wurde.
Das, was Du zitierst hast, war nur ein Beispiel dafür, dass man in settern mehr machen kann, als nur den Wert zu setzen. In Bezug auf Deinen Code ist es nicht sinnvoll, das Zitierte zu implementieren.
Üblicherweise werden, soweit nötig, in Settern Konsistenzprüfungen vorgenommen oder abhängige Attribute mit berechnet. Möglich ist natürlich auch, durch das Setzen eines Attributs den Zustand des Objekts zu ändern.
Dazu ein paar Beispiele:
In einer Klasse Kreis könnte in setRadius($meter) gleich der Umfang und die Fläche neu berechnet werden. Es ließe sich auch vorstellen, dass es nur das (private) Attribut Radíus gibt und dieser in einer setUmfang($meter)-Methode berechnet und gesetzt wird. getUmfang() und getFlaeche() wären dann Getter für Attribute, die es in der Klasse selbst nicht gibt, und die bei Aufruf jedesmal berechnet werden. Dadurch lässt sich z.B. berücksichtigen, ob überwiegend lesend oder schreibend auf die Klasse zugegriffen wird. Je nach dem kann man, aus Performancegründen, die Werte vorberechnen oder bei Abfrage berechnen.
In einer Klasse Uhrzeit könnte die setStunde-Methode berücksichtigen, dass ein Tag nur 24 Stunden hat und bei größeren Werten die Stunde nicht neu setzt, sondern einen Fehler zurück gibt oder eine Exception (sorry, ich glaub, das gibts in PHP nicht) werfen.
In einer Klasse Datenbank könnte es statt den Methoden connect() und disconnect() einen Setter setConnected($boolean) geben, welche den Verbindungsstatus setzt und interne Methoden zur Verbindungssteuerung aufruft.

@_voodoo:
private: Nur Methoden der Klasse können auf die Variable zugreifen.
public: Auf die Variable kann von überall zugegriffen werden.
protected: Hab ich in der PHP-Doku nicht gefunden. EDIT: Doch gefunden. Nur die Klasse selbst und ihre Erben haben Zugriff auf die Variablen.
Die Sichtbarkeit gilt meines Wissens sowohl lesend, als auch schreibend und ist wesentlicher Bestandteil der Kapselung, welche wesentlicher Bestandteil der objektorientierten Programmierung ist. (Es wurde also Zeit, dass diese Sichbarkeits-Attribute in PHP 5 eingeführt worden sind, wenn man mit PHP "anständig" objektorientiert Programmieren können soll.)
 
Zuletzt bearbeitet:
daddz hat gesagt.:
Der Setter für fMode ist doch berechtigt! Der User will vielleicht den Default Modus "w" in "w+" ändern!
Gute Idee, da bin ich nicht drauf gekommen (Kommentare fehlen :p ). Ich würde dann zwischen read- und write-mode unterscheiden (Du hast für beides ja auch eigene Funktionen) und Du solltest den gewählten Modus auch bei fopen verwenden ;)
 
Zurück