OOP in PHP: Daten automatisch löschen

Parantatatam

mag Cookies & Kekse
Hallo,

ich bin gerade wieder dabei mir eine Klasse zu basteln, welche man dann in etwa so aufrufen kann:
PHP:
$class = new Class();
$class->func_1()->func_2()->func_3() ... ->func_n();
Das habe ich bisher so gelöst, dass diese Klasse auf einer untergeordneten Klasse arbeitet.

Wo liegt mein Problem?
Mein Problem liegt darin, dass man nicht nur die Methoden so aufrufen soll ($a->func1()->func2()->func3()) sondern auch mal so ($a->func1()->func2()). Es gibt also Methoden, die man an andere noch extra anhängen kann, aber nicht muss. Die Schwierigkeit ist jetzt, dass ich einzelnen Daten intern zwischen speichere und dann in der letzten Methode in dieser Reihe ausführen will. Die Frage ist nur, ob es eine Möglichkeit gibt, dass man erkennt, ob eine Methode die Letzte in einer Reihe ist. Was auch gehen würde, wäre wenn man vor dem Aufrufen einer solchen Methoden-Reihe die Daten zurücksetzt - Frage ist nur wie.

Ich hoffe, ich konnte das verständlich erklären. Ansonsten noch mal nachfragen und schon jetzt Danke an alle, die mir helfen wollen/können.
 
Zuletzt bearbeitet:
So. Ich habe mir mal ein kleines Beispiel dafür programmiert, ähnlich dem Beispiel im PHP Handbuch.
PHP:
<?php
class test
 {
  function test1()
   {
    echo 'Ich bin die Methode test1()'."\n";
   }
  
  function test2()
   {
    echo 'Ich bin die Methode test2()'."\n";
   }
  
  function __call($name, $args)
   {
    echo 'Methodenname: '.$name."\n";
   }
  
 }

$test = new test;
$test->test1();
$test->test2();
?>

Jetzt müsste mir ja ausgegeben werden..
Code:
Ich bin die Methode test1()
Methodenname: test1
Ich bin die Methode test2()
Methodenname: test2
..aber leider wird nur folgendes ausgegeben:
Code:
Ich bin die Methode test1()
Ich bin die Methode test2()

Ich benutzte die PHP Version 5.2.5 - liegt es jetzt daran, dass ich eine zu niedrige PHP Version habe oder das ich diese Methode falsch anwende? Eine Suche bei Google ergab keine eindeutige PHP Version ab welcher die Methode __call() verfügbar ist.

// EDIT: Ich habe jetzt mit Hilfe von dieser Seite erfahren, dass diese Methode dafür da ist, dass falls eine unbekannte Methode aufgerufen wird diese als Ersatz aufgerufen wird, somit ist mein Beispiel oben verständlicher Weise Blödsinn.
 
Zuletzt bearbeitet:
An saftmeister: ich habe jetzt noch mal überlegt und bin jetzt soweit gekommen, dass ich überhaupt nicht verstehe auf welche Art und Weise mir die Methode __call() helfen soll. Könntest du mir deinen Gedankengang noch mal schildern? Wäre ganz nett.
 
Hallo,

ich denke, ich habe deinen Ausgangspost falsch verstanden:

Es gibt also Methoden, die man an andere noch extra anhängen kann, aber nicht muss.

Ich bin davon ausgegangen, das du meintest, die Methoden müssen nicht unbedingt implementiert werden. Genau dann, wenn eine Methode in einer Klasse _nicht_ unbedingt definiert sein muss, kann man __call() verwenden. Da du es anscheinend anders gemeint hast, ist mein Vorschlag natürlich obsolet. __call() reagiert auf einen Methoden-Aufruf einer Klasse, die die aufgerufene Methode _nicht_ implementiert.

Was du bräuchtest, wäre eine Art Objekt-Proxy. Ich habe sowas noch nicht gemacht, da ich es nicht benötigt habe. Vielleicht kannst du jedoch mit diesem Stichwort irgendwas finden.
 
Danke, dass klingt schon viel versprechend. Melde mich wieder, wenn ich was gefunden habe (oder immer noch nicht weiter weiß).
 
Leider habe ich gerade nicht die Zeit mich selbst damit zu befassen, aber die Datenbank-Klasse von TYPOlight nutzt diese Art der Methodenaufrufe.
(Weiss ich auch nur, da ich ein Modul dafür entwickel.)

Kannst ja mal schauen wie das dort gemacht ist. :)

Würde mich nämlich auch interessieren, wie das abläuft. ;)
 
an DeluXe: Ich habe mir die Datenbank Klasse mal angesehen und muss sagen, dass das schon langsam in die Richtung geht, die ich suche. Aber eben noch nicht ganz. Ich zeige euch mal, wie das in TYPOlight gelöst wurde:
PHP:
function __get($func)
 {
  switch($func)
   {
    case 'func1':
     return $this->func1();
     break;
   
     case 'value':
      return $this->value;
      break;
    
     default:
      return $this;
      break;
   }
 }

Das hat aber als Nachteil, dass dann nur am Ende der Kette eine Funktion stehen kann. Die Frage wäre nun, wie man dass auch für Funktionen erreicht, also genauer gesagt, wie man eine geregelte Verkettung erstellen kann.
 
Entweder verstehe ich dich falsch oder du liegst falsch. :)

Weil in TL kann man z. B. mit diesem Befehl eine Query ausführen:
PHP:
$db->prepare( 'SELECT * FROM foo WHERE bar = %d' )->execute( $int );

Und das sind ja zwei Funktionen hintereinander, nicht nur eine am Ende.
 
Mh, dass stimmt natürlich. Ich habe jedenfalls gestern Abend nur die obenstehende Lösung gefunden. Dann werde ich wohl weitersuchen müssen. Du könntest mir aber helfen in dem du mir sagst auf welche PHP-Datei du dich beziehst, da es in TYPOlight mehrere Datenbank-Klassen gibt.

// EDIT: Ich habe es jetzt nicht gefunden, aber dafür habe ich jetzt noch mal selber intensiv nachgedacht und bin zu folgender Lösung gekommen, welche auch funktioniert und die von saftmeister genannte Funktion __call() verwendet:
PHP:
function __call($name, $args)
 {    
  switch($name)
   {
    case 'func2':
     return $this->sub_func2($args);
    
    case 'func3':
     return $this->sub_func3($args);
    
    case 'func4':
     return $this->sub_func4($args);
    
    default:
     trigger_error('Call to undefined method '.__CLASS__.'::'.$name.'()', E_USER_ERROR);
     return NULL;
   }
 }
Die Idee die dahinter steckt ist die, dass man so nur bestimmte Funktionen, welche als private gekennzeichnet werden, aufrufen kann. Um sie zu kennzeichnen habe ich hier einfach die Markierung sub_ verwendet. Man kann also jetzt in der Funktion __call() auch noch nachschauen, ob diese Funktion an dieser Stelle überhaupt gültig ist und man sie so aufrufen darf. Ansonsten wird eben NULL ausgegeben und damit es ein wenig wie echt wirkt auch noch die Standard-Fehlermeldung mit trigger_error().

Würde mal gerne wissen, was ihr von der Idee haltet. Verbesserungsvorschläge sind erwünscht!
 
Zuletzt bearbeitet:
Zurück