dedlfix: HTTP-Cache

Beitrag lesen

echo $begrüßung;

Im Moment lasse ich die Storage-Engine (man, klingt das cool *g*) von HTTPCache erben, dann muss nichtmal HTTPCache beibringen, unterschiedliche Storage-Engines zu verwenden, sondern man muss nur noch die gewünschte Storage-Engine einbinden.

Ich halte das für nicht optimal,[...]

Warum nicht? Was spricht denn dagegen? Wenn man z.B. einen Feedreader schreibt muss nur HTTPCache requiren, die Storage-Engine requiren und sich ein Objekt davon besorgen.

Du sparst dir vielleicht in diesem kleinen überschaubaren Fall die Instantiierung der Storage-Engine. Doch wenn deine Projekte mal größer werden, kannst du nicht einfach eine riesige Vererbungskette aufbauen, nur um irgendwas zu sparen.
Der Sinn von Klassen ist, einer abgeschlossene Funktionalität einen geeigneten Rahmen zu geben. Wenn du eine große Erbmasse erstellst, kannst du auch gleich die Klassen weglassen und alles im globalen Adressraum ablegen.
Wenn dein Lebensmittelhändler die Aufgabe hat, Lebensmittel zu besorgen, musst du als Kunde nicht von ihm erben. Als Erbe bekommst du unnötigen Zugriff auf all seine Eigenschaften. Da kann es dann schon mal zu Problemen beim Zugriff auf $this->portemonnaie geben. Das will weder der Händler, noch du. Er hat seine abgeschlossene Aufgabe, du hast deine. Wenn du seine Leistungen nutzen willst, bediene dich ihrer an den vom Händler bereitgestellten Schnittstellen, aber verleibe ihn dir nicht ein.

Ansonsten müsste man umständlich der Klasse HTTPCache erklären, welche Storage-Engine sie instanzieren soll.

Es ist kein großer Unterschied, ob du ein um "DB" erweiterten Klassennamen ansprichst, oder das "DB" als Parameter übergibst. Und ein

function engine_factory($engine_type)
  $engine_name = 'Engine_' . $engine_type;
  $engine_file = $engine_name . '.php';

if (!file_exists($engine_file)) {
    fehler('Klassendatei nicht gefunden');
    return false;
  }

require_once $engine_file;

if (class_exists($engine_name) and is_a($engine = new $engine_name(), 'Engine'))
    return $engine;

fehler('Engineerzeugungsfehler');
  return false;
}

ist schnell geschrieben. (Wieder kommt ein Pattern zum Einsatz, diesmal das factory pattern.)

Also wenn ich so eine Methode habe, bekomme ich dann unter PHP 4 und PHP 5 immer nur die Referenz?

Nein, PHP4 und 5 arbeiten da unterschiedlich. PHP4 kopiert, PHP5 referenziert.

/**

  • Gibt eine Instanz des Caches zurück.
    */
    function getInstance() {
      static $conn = null;

if ($conn == NULL) {
   $conn = &new HTTPCacheDB();
   $conn->open();
  }

return $conn;
}

  
So ist das weder unter PHP4 noch unter PHP5 sinnvoll.  
PHP4: Du erzeugst eine neue Instanz von HTTPCacheDB, übergibst eine Referenz darauf. Das ist, wie ich schrieb nur in besonderen Ausnahmefällen notwendig. Das Handbuch empfiehlt, nicht auf Teufel komm raus zu referenzieren, sondern nur da, wo man wirklich eine Referenz braucht. "Do not use return-by-reference to increase performance, the engine is smart enough to optimize this on its own. Only return references when you have a valid technical reason to do it!" Diesen Grund sehe ich bei HTTPCacheDB nicht.  
Du solltest aber die Referenz so wie in meinem Vorposting-Beispiel verwenden. Ob du nun die wirklich erzeugte Instanz oder eine Kopie davon in $conn ablegst, ist technisch gesehen egal. Für den weiteren Verlauf ist es an der Stelle unwichtig, dass es nur eine Kopie ist. Das Original ist nicht mehr ansprechbar und geht in die ewigen Jagdgründe. Es gibt keinen Konflikt zwischen den beiden.  
Wenn du aber $conn an den Aufrufer von getInstance übergeben willst ist es schon wichtig, ob du eine Kopie oder das Original rausgibst. Wenn der Aufrufer eine Kopie ändert, bekommt der nächste Aufrufer eine neue jungfräuliche Kopie ohne die Änderungen der anderen Aufrufers. Das kann so gewollt sein oder auch nicht.  
PHP5: Hier gibt es generell Referenzen. In der Notation $x =& new foo(); ist das & überflüssig. Ansonsten würde dein Beispiel von sich aus Referenzen zurückgeben.  
  
  
echo "$verabschiedung $name";