/OOP Pseudovariable $this
Fabian St.
- php
0 Tom0 Daniel Thoma0 Fabian St.0 Anonymous
0 dedlfix0 Fabian St.0 dedlfix
0 fanelf.de
Hi!
Mit der Pseudovariable $this kann ein Objekt bekanntlich auf seine eigenen Instanzvariablen und Methoden zugreifen. Jetzt habe ich mir mal eine ziemlich einfache Klasse geschrieben, die die Dateien eines Verzeichnis in ein Array schreibt [1]:
class Dir2Array
{
private $dir;
private $_files = array();
private $file;
private $handle;
public function __construct($path)
{
$this->dir = $path;
$this->handle = opendir($this->dir);
}
public function browse()
{
while(($this->file = readdir($this->handle)) !== FALSE)
{
if($this->file != '.' && $this->file != '..')
{
$this->_files[] = $this->file;
}
}
return $this->_files;
}
public function __destruct()
{
closedir($this->handle);
}
}
Mein Frage ist nun, warum die Funktion auch das tut, was sie soll, wenn man z.B. schreibt:
if($file != '.' && $file != '..')
{
$_files[] = $file;
}
Hier lasse ich das $this weg und das Objekt sollte doch eigentlich nicht mehr auf die Variablen zugreifen können. Man erhält im Übrigen auch keinen Fehler/Warnung/Notice angezeigt[2].
Wie ist das möglich?
Grüße,
Fabian St.
[1] Sorry, für soviel Quelltext, aber so glaube ich ist es einfacher, das
Problem nachzuvollziehen.
[2] auch bei error_reporting(E_ALL) und ini_set('track_errors', 1)
Hello,
Mein Frage ist nun, warum die Funktion auch das tut, was sie soll, wenn man z.B. schreibt:
Welche PHP-Version?
Harzliche Grüße aus http://www.annerschbarrich.de
Tom
Hi Tom!
Mein Frage ist nun, warum die Funktion auch das tut, was sie soll, wenn man z.B. schreibt:
Welche PHP-Version?
PHP 5.0.3 als Apache-Modul. An den "Zugriffsbarkeiten" public, private hätte man dies im übrigen auch erkennen können, da obiger Code in PHP 4 nicht lauffähig wäre. ;-)
Grüße,
Fabian St.
Hallo Fabian,
Wie ist das möglich?
$this benötigt man nur, wenn es eine lokale Variable gleichen Namens gibt. Es ist z.B. üblich, Parameter von Funktionen und Konstruktoren genau so zu benennen, wie Instanzvariablen, wenn der Wert aus dem Parameter in der Instanzvariable gespeichert werden soll:
function setBla(bla) {
$this->bla = bla;
}
Grüße
Daniel
Hi Daniel!
Wie ist das möglich?
$this benötigt man nur, wenn es eine lokale Variable gleichen Namens gibt. Es ist z.B. üblich, Parameter von Funktionen und Konstruktoren genau so zu benennen, wie Instanzvariablen, wenn der Wert aus dem Parameter in der Instanzvariable gespeichert werden soll:function setBla(bla) {
$this->bla = bla;
}
Du meinst wohl
function setBla($bla) {
$this->bla = $bla;
}
bla wird ja wohl keine Konstante sein. ;-)
Abgesehen davon kann man dann also sagen, dass man $this benutzt, um die Instanzvariablen eines Objektes von anderen Variablen, die auch in der Klasse vorkommen, z.B. als Parameter verschiedener Funktionen, unterscheiden zu können. Demnach ist die Methode mit $this->_files bzw. $this->file in meinem obigen Code sauberer.
Ist das soweit richtig?
Grüße,
Fabian St.
Hallo Fabian,
bla wird ja wohl keine Konstante sein. ;-)
Ja, die Syntax von PHP kenne ich nicht so genau. Ich kenne PHP quasi nur vom Begutachten oder Korregieren fremden Codes.
Abgesehen davon kann man dann also sagen, dass man $this benutzt, um die Instanzvariablen eines Objektes von anderen Variablen, die auch in der Klasse vorkommen, z.B. als Parameter verschiedener Funktionen, unterscheiden zu können. Demnach ist die Methode mit $this->_files bzw. $this->file in meinem obigen Code sauberer.
Naja, über "sauberer" kann man sich streiten. Auf jeden Fall umständlicher.
In den meisten Fällen verzichtet man auf das this, damit der Code knapper wird.
Wenn es sonst verwirrend wäre oder Du das einfach verständlicher findest, kann man $this aber auch verwenden, wenn man es nicht unbedingt braucht.
Meines Wissens gibt es keinen anderen Fall, wo man $this zwingend braucht.
Grüße
Daniel
Hi Daniel!
Naja, über "sauberer" kann man sich streiten. Auf jeden Fall umständlicher.
In den meisten Fällen verzichtet man auf das this, damit der Code knapper wird.
Mit "sauberer" meine ich, dass es mit dem $this->variable eigentlicher richtig wäre.
Wenn es sonst verwirrend wäre oder Du das einfach verständlicher findest, kann man $this aber auch verwenden, wenn man es nicht unbedingt braucht.
OK, dann werde ich es wohl weiter verwenden, weil es mir einleuchtender erscheint.
Vielen Dank für deine Hilfe!
Grüße,
Fabian St.
Wie ist das möglich?
$this benötigt man nur, wenn es eine lokale Variable gleichen Namens gibt.
Das stimmt erst ab PHP5.
echo $begrüßung;
Mein Frage ist nun, warum die Funktion auch das tut, was sie soll, wenn man z.B. schreibt:
if($file != '.' && $file != '..')
{
$_files[] = $file;
}
Bei mir (5.0.4) tut sie nicht was sie soll, sondern das was dasteht und erzeugt eine (mehrere) astreine Notice aufgrund der nicht vorhandenen Variable $file.
Ist dafür etwa ein Konfigurationsparameter verantwortlich?
> [2] auch bei error\_reporting(E\_ALL)
Du schreibst das als Funktionsaufruf. Nicht dass du das vielleicht doch in der Per-Verzeichnis-Konfiguration als
php\_value error\_reporting E\_ALL
stehen hast? Dort funktionieren nur Zahlenwerte.
Ich will ja nur sicher gehen...
echo "$verabschiedung $name";
Hi Felix!
Mein Frage ist nun, warum die Funktion auch das tut, was sie soll, wenn man z.B. schreibt:
if($file != '.' && $file != '..')
{
$_files[] = $file;
}
> Bei mir (5.0.4) tut sie nicht was sie soll, sondern das was dasteht und erzeugt eine (mehrere) astreine Notice aufgrund der nicht vorhandenen Variable $file.
Hm, komisch. Ich kann mir kaum vorstellen, dass sich beim Versionswechsel von 5.0.3 auf 5.0.4 soviel getan hat. Hast du bereits mal versucht, die Schleife ebenfalls zu verändern? Also:
~~~php
while(($file = readdir($this->handle)) !== FALSE)
Was passiert dann bei dir? Bei mir funktioniert die Klasse weiterhin. Mir geht es bei meiner Frage vor allem darum, was der Unterschied ist, wenn ich einmal schreibe $this->file oder $file. Sind das zwei verschiedene Variablen?
Ist dafür etwa ein Konfigurationsparameter verantwortlich?
Keine Ahnung woran das liegen könnte. Meine php.ini ist soweit default-mäßig, nur post_max_size und max_execution_time und max_input_time sind von mir verändert.
Du schreibst das als Funktionsaufruf. Nicht dass du das vielleicht doch in der Per-Verzeichnis-Konfiguration als
php_value error_reporting E_ALL
stehen hast? Dort funktionieren nur Zahlenwerte.
Ich will ja nur sicher gehen...
Beide Anweisungen befinden sich in Zeile 2 und 3 der Datei - in der .htaccess stehen keine Konfigurationswerte für PHP.
Grüße,
Fabian St.
re
Hm, komisch. Ich kann mir kaum vorstellen, dass sich beim Versionswechsel von 5.0.3 auf 5.0.4 soviel getan hat.
Ich auch nicht.
Hast du bereits mal versucht, die Schleife ebenfalls zu verändern? Also:
while(($file = readdir($this->handle)) !== FALSE)
Was passiert dann bei dir?
Dann gibt die Funktion in jedem Fall ein leeres Array zurück ohne, dass sich PHP beschwert.
Erst wenn ich beim return auch noch das $this weglasse, dann erhalte ich ein gefülltes Array. Was ja dann auch logisch ist. Allerdings wird damit immer noch nicht $instanceOfDir2Array->_files gefüllt.
(Jetzt komm mir nicht mit dem Argument, dass $_files private ist. :-) Ich hab mir $instanceOfDir2Array mit print_r()/var_dump() angesehen.)
Mir geht es bei meiner Frage vor allem darum, was der Unterschied ist, wenn ich einmal schreibe $this->file oder $file. Sind das zwei verschiedene Variablen?
Das behaupte ich immer noch, solange ich das nicht anhand einer nachvollziehbaren Testbedingung (eindeutige Konfigurationsparameter) widerlegt bekomme.
$file ist innerhalb von Dir2Array::browse() eine lokale Variable - so wie das auch in Stino-Funktionen der Fall ist - und $this->file ist die Klassenvariable der aktuellen Instanz.
Wobei sich mir die Frage stellt, warum du $file und $_files überhaupt als Klassenvariablen deklarierst und sie dann nur lokal verwendest. Es sei denn, deine Klasse hat noch ein paar mehr Methoden, die du hier nicht zitiert hast.
Außerdem, finde ich, fehlt in deinen Quelltext eine Einrückungsebene. Der gesamte Klasseninnenraum müsste einen Tabulator (oder eine Anzahl Leerzeichen) nach rechts.
dedlfix
Glossar:
stino : stinknormal
Hi!
re
An diese Art der Begrüßung muss ich mich noch gewöhnen ;-)
Mir geht es bei meiner Frage vor allem darum, was der Unterschied ist, wenn ich einmal schreibe $this->file oder $file. Sind das zwei verschiedene Variablen?
Das behaupte ich immer noch, solange ich das nicht anhand einer nachvollziehbaren Testbedingung (eindeutige Konfigurationsparameter) widerlegt bekomme.
$file ist innerhalb von Dir2Array::browse() eine lokale Variable - so wie das auch in Stino-Funktionen der Fall ist - und $this->file ist die Klassenvariable der aktuellen Instanz.
Wobei sich mir die Frage stellt, warum du $file und $_files überhaupt als Klassenvariablen deklarierst und sie dann nur lokal verwendest. Es sei denn, deine Klasse hat noch ein paar mehr Methoden, die du hier nicht zitiert hast.
Jetzt lüftet sich das ganze :-) Vor lauter OOP verliert man leicht den Überblick über das Altbewährte. Ich habe vollkommen vergessen, dass $file und $_files ja eigentlich nur innerhalb der Methode browse() verkommen. Demnach ist es - wie du auch bemerkt hast - unsinnig, $file und $_files als Klassenvariablen der aktuellen Instanz zu deklarieren. Sie sollten einfach innerhalb der Methode browse() deklariert werden... Ich habe den Wald vor lauter Bäumen nicht gesehen.
Eine kleine Frage hätte ich da aber noch: Ich dachte, man kann mit dem 'Scope Resolution Operator' (::) nur auf statische Variablen und Methoden zugreifen. Du verwendest jetzt jedoch Dir2Array::browse() - darf man das so einfach machen, immerhin handelt es sich dabei um eine als public deklarierte Methode?
Außerdem, finde ich, fehlt in deinen Quelltext eine Einrückungsebene. Der gesamte Klasseninnenraum müsste einen Tabulator (oder eine Anzahl Leerzeichen) nach rechts.
Das hatte er eigentlich auch, nur die Forumsoftware hat diese Einrückungen auf nur ein oder zwei Zeichen verkürzt. Damit mein Code ordentlich formatiert ist, sorgt im übrigen Eclipse mit dem PHP-Plugin. Bisher hatte ich ja Bluefish bzw. Quanta benutzt, aber ein Debugger gleich beim Entwickeln ohne sich erst das betreffende Skript im Browser anzuschauen müssen, ist ziemlich praktisch und erleichtert das Arbeiten ungemein.
Grüße,
Fabian St.
Hi!
Mit der Pseudovariable $this kann ein Objekt bekanntlich auf seine eigenen Instanzvariablen und Methoden zugreifen. Jetzt habe ich mir mal eine ziemlich einfache Klasse geschrieben, die die Dateien eines Verzeichnis in ein Array schreibt [1]:
this oder self sind keine pseudovariablen, sondern bezeichnen die eigene instanz einer klasse. man macht dies zur abgrenzung zu anderen instanzen.
in der modernen oop hat sich aber eingebürgert, dass die sicht auf die eigene instanz weggelassen werden kann. du hast ja die variable in der klasse deklariert. anders sähe es aus, wenn du eine referenz auf ein anderes objekt hättest. dieses müßtest du selbstverständlich prefixen.
Mein Frage ist nun, warum die Funktion auch das tut, was sie soll, wenn man z.B. schreibt:
Hier lasse ich das $this weg und das Objekt sollte doch eigentlich nicht mehr auf die Variablen zugreifen können. Man erhält im Übrigen auch keinen Fehler/Warnung/Notice angezeigt[2].Wie ist das möglich?
ich habe es nicht ausprobiert, aber mit php5 will man sich mit oop ja weiterentwickeln. ich denke, daß auch dies dazu gehört.