php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 07.04.2005, 15:12  
Gast
 
Beiträge: n/a
Standard [Erledigt] Design Pattern - MySQL Sitzung in allen Objekten nutzen

Hi,
es gibt ja ein bekanntes Pattern, in dem man in eine statische Eigenschaft einer Klasse ein Objekt legt, so dass man dieses immer leicht her hohlen kann.

Ein Beispiel (Java):
Code:
    public class Test {
      static m_oDb;

      static getCurrentDb() {
        if (Test.m_oDb == null) {
          // Init Db
        }
      return Test.m_oDb;
      }
    }
So etwas wollte ich auch auf meiner Homepage nutzen. Da meine "Homepage-Software" nicht nur von mir, sondern auch von anderen Leuten benutzt wird, kann ich die Seite leider nicht in PHP5 schreiben, in welchem es das Schlüsselwort "static" gibt. Ich möchte eine Lösung haben, die mindestens auf PHP 4.3 läuft.

Im Moment habe ich das leider noch sehr unsauber gelöst:

Code:
    // In der Main-Datei
    $myDb =& DB::connect(); // usw


    // Bei der speziellen Klasse
    class MyClass {
      var $m_oDb;

      function MyClass() {
        $this->m_oDb =& $GLOBALS['myDb'];
      }
    }
Nun fällt auf, dass dieser Quelltext nicht gut wieder verwendet werden kann, da jeder Programmierer die Db auf einer bestimmten Variablen ablegen muss.

Zudem habe ich ein 2. Problem, welches auch mit meinem Programmier-Design zusammen hängt. Ich habe meine Klassen in verschiedene "Manager" aufgeteilt, welche wie gewohnt eine bestimmte Aufgabe lösen (ContentManager, FormManager,...).

Nun:
1. Gibt es für die Datenbanken ein Möglichkeit, das ganze so zu gestalten, dass der Quelltext möglichst wiederverwendbar bleibt? (Ich möchte die Db möglichst nicht an den Konstruktor übergeben.)

2. Sollte ich Smarty so ähnlich wie die Db behandeln, oder sollte ich dieses Objekt/Klasse möglichst getrennt von meinen Managern halten und diese in der Main Datei manuell "assignen". Also
- $content->registerInfos(); oder
- $smarty->assign('info', $content->getInfos());

Ich hoffe, ihr könnt mir ein paar Anregungen oder Antworten geben.

Mfg
  Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 07.04.2005, 16:14  
Gast
 
Beiträge: n/a
Standard

hi,

du solltest niemals globals in deinem code benutzen. falls du doch globale objekte benötigst dann ist der singleton schon die richtige wahl. alternativ kannst du dir auch mal anschauen was eine registry ist.

zur implementation :

PHP-Code:
class Singleton
{
  function &
getInstance()
  {
     static 
$instance;
     if (!isset(
$instance))
     {
       
$instance = &new Singleton();
     } 
     return 
$instance;
  }

gruss
Sike


ps. http://www.phppatterns.com/index.php...leview/75/1/1/
  Mit Zitat antworten
Alt 07.04.2005, 16:34  
Gast
 
Beiträge: n/a
Standard

Hi,
das ist ja genau das, was ich in meinem Java-Beispiel geschrieben habe. Jedoch bekomme ich dort ein Problem mit PHP4 bzw. PHP5.

Mein Script soll unter beidem laufen!

Auf meinem aktuellen Testcomputer habe ich mal ein kleines Testscript geschrieben:
PHP-Code:
<?php
error_reporting
(E_ALL);

class 
Test {
  public static 
$foo;
  var 
$bar;

  public static function &
getPhp5Instance() { 
    return 
Test::$foo 'test';
  }

  function &
getPhp4Instance() {
    return 
Test::$bar 'test';
  }
}

echo 
Test::getPhp5Instance();
echo 
'
'
;
echo 
Test::getPhp4Instance();
?>
Einmal habe ich eine Statische Methode mit den PHP5-Keywörtern (die schon längst überfällig waren) geschrieben und einmal ohne, so, dass PHP4 was damit Anfangen könnte. Unter PHP4 bekomme ich natürlich Fehler, dass es die static Keywörter nicht kennt.

Deshalb wollte ich das über den nicht so schönen Weg wie in PHP4 machen. Nun, PHP5 kommt damit nicht klar. Ich bekomme die Fehlermeldung:
Zitat:
Fatal error: Access to undeclared static property: Test::$bar in E:\www\test\static.php on line 13
.

Ich stehe im Moment ziehmlich auf dem Schlauch, wie ich das so hinbekommen könnte, dass das auf allen PHP Versionen >4.3 läuft?

Mfg
  Mit Zitat antworten
Alt 07.04.2005, 17:18  
Waq
Erfahrener Benutzer
 
Registriert seit: 15.08.2004
Beiträge: 2.473
Waq
Standard Re: Design Pattern - MySQL Sitzung in allen Objekten nutzen

Von dem Pattern halte ich nichts.

Zitat:
Zitat von BoneCracker
(Ich möchte die Db möglichst nicht an den Konstruktor übergeben.)
Solltest Du aber.
Dass Du davon ausgehst, dass es nur eine Datenbankverbindung geben kann, und nicht mehrere, empfinde ich als stärkere Einschränkung der Wiederverwendbarkeit als die Verwendung einer globalen Variable.
Der ganze Aufwand, den Du hier betreibst, ist IMHO bestenfalls nen Becher warme Spucke wert.


Eine Möglichkeit, statische Klassenvariablen in PHP 4 umzusetzen, sind übrigens statische lokale Variablen in statischen Methoden:

PHP-Code:
class foo {
  function var (
$new_value null) {
    static 
$var;
    if (
$new_value)
      
$var $new_value;
    return 
$var;
  }

Das müsste auch unter PHP 5 gehen.
__________________
mod = master of disaster
Waq ist offline   Mit Zitat antworten
Alt 07.04.2005, 17:19  
Gast
 
Beiträge: n/a
Standard

erm... hast du dir mal mein beispiel genauer angeschaut?
das läuft genau so unter php4/5.

gruss
Sike

ps. falls du es nicht siehst schau dir mal an _wo_ ich die static variable unterbringe.
  Mit Zitat antworten
Alt 07.04.2005, 19:39  
Gast
 
Beiträge: n/a
Standard Re: Design Pattern - MySQL Sitzung in allen Objekten nutzen

Hi,
hätte ich doch genauer hinschauen müssen... Danke!

Zitat:
Zitat von Waq
empfinde ich als stärkere Einschränkung der Wiederverwendbarkeit als die Verwendung einer globalen Variable.
Ich hatte ja auch schon geschrieben gehabt, dass ich die aktuellen Lösung alles andere als gut finde.

Zitat:
Zitat von Waq
Von dem Pattern halte ich nichts.
Wieso? Eine Begründung wäre nicht schlecht...

Mfg
  Mit Zitat antworten
Alt 07.04.2005, 19:45  
Waq
Erfahrener Benutzer
 
Registriert seit: 15.08.2004
Beiträge: 2.473
Waq
Standard

Zitat:
Dass Du davon ausgehst, dass es nur eine Datenbankverbindung geben kann...
__________________
mod = master of disaster
Waq ist offline   Mit Zitat antworten
Alt 09.04.2005, 19:36  
axo
Erfahrener Benutzer
 
Registriert seit: 24.12.2004
Beiträge: 1.814
axo ist zur Zeit noch ein unbeschriebenes Blatt
Standard Re: Design Pattern - MySQL Sitzung in allen Objekten nutzen

Zitat:
Zitat von BoneCracker
Wieso? Eine Begründung wäre nicht schlecht...
kann ich nur bestätigen. das singleton ist im prinzip auch nichts anderes als eine globale variable - mit einem oop-mäntelchen.

ich hatte ein wunderbares framework, das eine eigene DB-abstraktion als singleton instanziiert hat... also hat ungefähr jede methode, die mit der datenbank zu tun hatte, ein $db = & singleton('DB'); drin.

alles schön und gut, alle teilen sich das objekt - aber was machst du, wenn du auf einmal nicht ein objekt der klasse MeineKleineDbAbstraktion, sondern der klasse DB_common brauchst?

dann kannst du in 50 klassen und 20.000 zeilen code alle singleton-aufrufe ändern und die schnittstellen erweitern. kostet ca. 2 tage und wenn du nicht ordentliche tests am laufen hast, kannst du das ganze vergessen.

ein anderer aspekt ist die testbarkeit ... ich persönlich verwende gern für die unit tests eine eigene datenbank und ein paar dummy-objekte. wenn man singletons benutzt, kann man damit gar nichts anfangen, denn man kann das verhalten der methoden nicht mehr von außen steuern.


mein derzeitiger tipp:
eine AbstractFactory / Factory, die referenzen auf die 'wichtigen' objekte hält.
wenn du ein singleton-artiges objekt haben willst, steuert das die factory.

PHP-Code:
<?php
class Factory {
   var 
$_db;
   function &
getDb() {
       if(
$this -> _db === null) {
            
$this -> _db = & new DB();
      } 
     return 
$this -> _db;
   }
}
?>
... die factory kannst du jedem objekt, das es benötigt, als referenz im konstruktor mitgeben.
und die factory alleine steuert, ob sie beim aufruf von getDb() eine neue instanz erzeugt oder immer wieder das selbe objekt zurückgibt.
axo ist offline   Mit Zitat antworten
Alt 20.04.2005, 11:38  
Gast
 
Beiträge: n/a
Standard Re: Design Pattern - MySQL Sitzung in allen Objekten nutzen

Zitat:
Zitat von Waq
Von dem Pattern halte ich nichts.

Zitat:
Zitat von BoneCracker
(Ich möchte die Db möglichst nicht an den Konstruktor übergeben.)
Solltest Du aber.
Dass Du davon ausgehst, dass es nur eine Datenbankverbindung geben kann, und nicht mehrere, empfinde ich als stärkere Einschränkung der Wiederverwendbarkeit als die Verwendung einer globalen Variable.
Der ganze Aufwand, den Du hier betreibst, ist IMHO bestenfalls nen Becher warme Spucke wert.
Warum sollte er das?
Eine Verbindung zu DB ist eigentlich immer der Fall weitere Connection sind eher Ausnahme aber selbst da lässt sich was machen.

In dem Beispiel braucht er nur die Reihenfolge der Instanzierung kennen und nehmen wir mal an das die 1. Instance Grundsätzlich die Hauptverbindung zur DB ist braucht er noch nicht mal mehr eine Variable zu übergeben.


PHP-Code:
<?php
class Foo {
    protected static 
$instance = array();
    protected 
$temp;
    
    private function 
__construct() {
    }
    
    public static function &
instantiate() {
        static 
$instance_nr;
        
$instance_nr++;
        if (!
is_object(Foo::$instance[$instance_nr]))
            
Foo::$instance[$instance_nr] = new Foo();
        else
            
Foo::$instance[$instance_nr] = Foo::instantiate();
        return 
Foo::$instance[$instance_nr];
    }
    
    public function &
getInstance($INr) {
        if (
is_object(Foo::$instance[$INr]))
            return 
Foo::$instance[$INr];
        else
            return 
NULL;
    }
        
    public function 
set($val) {
        
$this->temp $val;
    }
    
    public function 
out() {
        echo 
$this->temp;
    }
}

$foo Foo::instantiate();
$bar Foo::instantiate();

$foo->set("Instance 1");
$bar->set("Instance 2");

$temp Foo::getInstance(1);

$foo->out();
echo 
"
"
;
$bar->out();
echo 
"
"
;
$temp->out();
?>
  Mit Zitat antworten
Alt 20.04.2005, 13:06  
Waq
Erfahrener Benutzer
 
Registriert seit: 15.08.2004
Beiträge: 2.473
Waq
Standard Re: Design Pattern - MySQL Sitzung in allen Objekten nutzen

Zitat:
Zitat von LeoManiac
Zitat:
Zitat von Waq
Zitat:
Zitat von BoneCracker
(Ich möchte die Db möglichst nicht an den Konstruktor übergeben.)
Solltest Du aber.
Warum sollte er das?
Weil er von "Wiederverwendbarkeit" sprach. Und euer Weg da schlicht und ergreifend nicht hinführt.

Zitat:
Zitat von LeoManiac
Eine Verbindung zu DB ist eigentlich immer der Fall
"eigentlich immer"? Oxymoron.
Ich gehe eigentlich davon aus, dass die Leute hier im Profi-Forum auch mal an etwas komplexeren Projekten arbeiten, wo eben auch eigentlich uneigentliche Dinge schonmal gefordert werden.

Zitat:
Zitat von LeoManiac
In dem Beispiel braucht er nur die Reihenfolge der Instanzierung kennen und nehmen wir mal an das die 1. Instance Grundsätzlich die Hauptverbindung zur DB ist braucht er noch nicht mal mehr eine Variable zu übergeben.
Hui, ein parametrisiertes Singleton... warum genau das sch.eisse ist, hat axo doch schon beschrieben:
Zitat:
Zitat von axo
alles schön und gut, alle teilen sich das objekt - aber was machst du, wenn du auf einmal nicht ein objekt der klasse MeineKleineDbAbstraktion, sondern der klasse DB_common brauchst?

dann kannst du in 50 klassen und 20.000 zeilen code alle singleton-aufrufe ändern und die schnittstellen erweitern. kostet ca. 2 tage und wenn du nicht ordentliche tests am laufen hast, kannst du das ganze vergessen.
Die Weitergabe der Verbindung per Parameter hat einen grossen Vorteil: Sie ist die einfachste Variante um zu erreichen, dass Kindobjekte die Verbindung ihrer Eltern vererbt bekommen. Denn nur so reicht es, einem Objekt die nicht-Standard-DB-Verbindung zu übergeben, und auf einmal benutzt die Hälfte des Programmes eine andere DB.

Es geht hier schliesslich un "Wiederverwendbarkeit". Dafür darf die Klasse keine unnötig einschränkenden Annahmen machen (wie z.B. "nur eine DB-Verbindung"), und sie muss mit möglichst geringem Aufwand verwendbar sein. Die Übergabe eines Parameters kann vom Aufwand her ignoriert werden (da O(1)), die Konzeptionellen Vorteile der Übergabe als Parameter hingegen nicht.

Zitat:
Zitat von LeoManiac
selbst da lässt sich was machen.
Was Du erreichst, ist bestenfalls "Anpassbarkeit", aber nicht "Wiederverwendbarkeit". Wiederverwendbar bedeutet, dass ich das Ding veröffentlichen kann, ohne das Irgendjemand, der das Ding benutzt, über unnötig einschränkende Annahmen meines Codes stolpert.
Wiederverwendbar ist es, wenn es in der gleichen Form überall läuft. Wenn jemand den Code anpassen musste, ohne dass diese Anpassungen von allen anderen benutzt werden können, war es eben nur "anpassbar".

Und ich wiederhole nochmal, was axo schonmal gesagt hat: Das Singleton tut genau dasselbe wie eine globale Variable. Konzeptionell ist es das gleiche, die einzigen Unterschiede sind das angezogene OOP-Mäntelchen, dass bestenfalls nen Becher warme Spucke wert ist, und die Kapselung im Namensraum der Klasse, was etwas mehr Wert ist aber nicht viel.
__________________
mod = master of disaster
Waq ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
MySQL Server startet nicht mehr richtig... Datenbanken 16 03.03.2006 19:40
Suche Tipps für Persormance-Steigerung (Geld für Nützliches) Beitragsarchiv 18 16.08.2005 10:57
[Erledigt] Mysql Datenbanken Parallel nutzen ? Datenbanken 3 31.08.2004 20:24
[Erledigt] PHP5 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;a m p; MySQL Datenbanken 5 01.08.2004 05:47

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php statische mysql, java mysql singleton, mysql pattern, java mysql database class singleton, php4 statische klassenvariable, datenbank entwurfsmuster, manager pattern php, mysql objekte, php mysql design-patterns, verschiedene datenbanken entwurfsmuster, pattern datenbanken, php mysql klasse pattern, mysql design pattern, php registry, php registry pattern erweitert, registry pattern php mysql, mysql db registry pattern, wiederverwendbares mysql objekt java, php static mysql database connectzion, mysql objekt

Alle Zeitangaben in WEZ +2. Es ist jetzt 20:28 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.