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.03.2007, 20:21  
Benutzer
 
Registriert seit: 24.01.2005
Beiträge: 56
Melchior
Standard Gegenstück zu parent:: oder Singleton abstrakt implement. ??

Hi,

hab mal ne kleine Frage, und zwar habe ich Klassen, die ich mit Singleton instanzier. Dazu schreibe ich jedes Mal in den Klassenkopf die Singleton vars+methoden.

Jetzt habe ich probiert, die Singleton-Implementation in die Elternklasse auszulagern:

In der abstrakten Klasse steht dann irgendwie sowas in der Art

PHP-Code:
    // Singleton
    // $className var defines the current classname for the singleton pattern
    // and needs to be overridden in the concrete one
    
    #protected  static  $className;
    
static $instance;
    
    static function 
getInstance () 
    {    
        if (!isset(
$instance)) self::$instance = new child::$className;
        return 
self::$instance;
    }
    
// Singleton END 
Da ich zum instanzieren der eigentl. Klasse aber den Namen brauche, muss der ja in der konkreten Kind Klasse stehen.

Dachte das iss ja einfach und hab wollt die var $className überschreiben, was aber nicht geht.
Statische Vars lassen sich nämlich nicht überschreiben...

Was ich jetzt suche ist ne Möglichkeit, dass wenn in der Parent-Klasse getInstance() aufgerufen wird, dass ich auf ne Var von der Kind-Klasse zugreifen kann.
Für die Elternklasse gibts ja parent:: aber ein derivat für die Kindklasse dazu habe ich leider nicht gefunden.

Würde mich freuen wenn jmd einen Tipp hätte, hab echt keine Lust überalle den Singleton-Schmudder immer in den Klassen zu haben :D

gruß melchior
Melchior ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

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

Alt 07.03.2007, 20:32  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Du musst den Code ja nicht in die Kind-Klasse schreiben, aber du kannst das ganze ja von dort aus anstossen und dabei eben die Eigenschaft des Kindes übergeben.

Ein child:: o.ä. kenne ich nicht, das heißt aber nicht, dass es das nicht gibt.

Klingt aber etwas nach Design-Fehler.
Zergling-new ist offline   Mit Zitat antworten
Alt 07.03.2007, 20:35  
Benutzer
 
Registriert seit: 24.01.2005
Beiträge: 56
Melchior
Standard

ne child gibts nicht, das stimmt - war nur code von verschiedene trials :P
hab ja geschr. dass es nur so vom prinzip aussehen muss

das mit den "antriggern" hatte ich mir auch schon überlegt - fand es aber etw. unsauber.

Falls es halt keine andere Lösung gibt, muss ich es wohl so machen

gracie
melchior
Melchior ist offline   Mit Zitat antworten
Alt 07.03.2007, 20:36  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Worum gehts denn konkret bei den Klassen bzw. dem singleton?
(aus reinem Interesse, keine Belehrung geplant)
Zergling-new ist offline   Mit Zitat antworten
Alt 07.03.2007, 20:44  
Benutzer
 
Registriert seit: 24.01.2005
Beiträge: 56
Melchior
Standard

hehe ok, wenns keine Belehrung ist

Arbeite mit dem Zend Framework, das auf dem mvc-pattern basiert. Also Trennung von Models, Controller und Views.

Meine Models präsentieren die Datenschicht, die ja von der DB gelesen werden muss. Desw. hab ich mir ne eigene abstrakte Klasse geschrieben, die das Handling dafür übernimmt (executeSql, getNumhits, changeCounter usw). Die Klasse wird dann im in den einzelnen Models extended.

Da alle Models nur einmal existieren mach ich das mim Singleton. Vom Framework selbst gibts zwar auch nen objektspeicher, aber da müsste ich immer nachschauen ob schon eins existiert. Da ich knapp 30 Models hab, hab ich relativ wenig Lust um das Management zu kümmern.

gruß
m

ps: zend framework anschauen, wenn noch nicht getan!
Melchior ist offline   Mit Zitat antworten
Alt 08.03.2007, 04:26  
Erfahrener Benutzer
 
Registriert seit: 13.08.2007
Beiträge: 1.976
KingCrunch befindet sich auf einem aufstrebenden Ast
KingCrunch eine Nachricht über ICQ schicken KingCrunch eine Nachricht über AIM schicken KingCrunch eine Nachricht über MSN schicken KingCrunch eine Nachricht über Yahoo! schicken
Standard

Benutze Zend auch und hatte eigentlich nie das Problem, dass ich zweimal ein Model instanziere Also jetzt mal aus der Praxis heraus lohnt sich das an den Punkt recht wenig. Ich lad mein Model direkt per new in der abstrakte Controller-Klasse und sicher es in ein Property. Da ja eh nur der Controller interesse am Model hat, reicht das Den Rest sauber programmieren und eben nicht das Model ein zweites mal instanzieren (hat in View oder Model eh nix zu suchen) und das passt scho.

Warum eigentlich? Ich vermisse sonst den Konstruktor
__________________
Nicht jeder Fehler ist ein Bug.
KingCrunch ist offline   Mit Zitat antworten
Alt 08.03.2007, 23:22  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hallo Melchior,

hierzu ist es ratsam eine abstrakte Singlton-Klasse zu implementieren, die die Aufgaben für dich übernimmt und einen Singleton-Cache definiert.
Dazu kann ich dir folgenden Code zeigen (kommentare habe ich entfernt; ist eine PHP 4 Implementierung). Anwenden tust du das dann in deinem Code mit


PHP-Code:
$oMgr = &Singleton::getInstance('myManager'); ?> 
Hier der Code:

PHP-Code:
   class Singleton
   
{

      
pfunction Singleton(){
      }


      function &
getInstance($className){

         
// Prüfen, ob Instanz des Objekt bereits existiert
         
if(!Singleton::isInSingletonCache($className)){

            
// Erzeugt Klasse $className singleton
            
$GLOBALS[Singleton::showCacheContainerOffset()][Singleton::createCacheObjectName($className)] = new $className;

          
// end if
         
}

         
// Gibt Instanz aus Singleton-Cache zurück
         
return $GLOBALS[Singleton::showCacheContainerOffset()][Singleton::createCacheObjectName($className)];

       
// end function
      
}


      function 
isInSingletonCache($className){

         if(isset(
$GLOBALS[Singleton::showCacheContainerOffset()][Singleton::createCacheObjectName($className)])){
            return 
true;
          
// end if
         
}
         else{
            return 
false;
          
// end else
         
}

       
// end function
      
}


      function 
createCacheObjectName($className){
         return 
strtoupper($className);
       
// end function
      
}


      function 
showCacheContainerOffset(){
         return (string)
'SINGLETON_CACHE';
       
// end function
      
}

    
// end class
   
}
?> 
Have fun!
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Alt 22.07.2007, 16:48  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Ich möchte das Thema nochmal ausbuddeln, um meine frisch gebackene php5 Singleton Variante zur Diskussion zu stellen.
Ziel war es, die Singleton Funktionalität weitgehend in eine eigene Klasse auszulagern, die auch die Instanzen vorhält. Da mir die Variante Singleton::createInstance (SingletonName [, Args ]); nicht so richtig gefällt, habe ich die Kindklasse mit einer Methode getInstance () ergänzt, so dass über den Klassennamen selbst ebenfalls eine Singleton-Instanz erzeugt werden kann. Es gibt also zwei Möglichkeiten, ein neues Singletonobjekt zu erzeugen.
Der Konstruktor der Kindklasse wird quasi als Presetting Methode mißbraucht.

PHP-Code:
<?

class Singleton 
  
{
  
# -- numerisches Array aus Singleton Objekten
  
private static $aUniqueInstances = array ();

  protected function 
__construct () {}
  private final function 
__clone () {}

  public static final function 
createInstance ()
    {
    
$aArguments func_get_args ();

    
# -- 1. Argument ist Klassenname, weitere werden an Konstruktor übergeben
    
$sClassname array_shift ($aArguments);

    
# -- für den Fall, dass Singleton (nichtstatische) Methoden nutzen soll:
    #    ohne Klassennamen-Attribut die Singleton Klasse selbst instanzieren
    
if (NULL === $sClassname$sClassname 'Singleton';

    
# -- Referenz auf Singleton Objekte, wenn NULL neue Instanz erzeugen
    
$oInstance = & self::$aUniqueInstances[$sClassname];
    if (
$oInstance === NULL
      {
      
$oInstance = new $sClassname;

      
# -- __construct der Klasse aufrufen, um darin definierte Presettings 
      #    auszuführen, genutzt werden die Attribute, die der Methode
      #    createInstance () übergeben werden
      
if (true === method_exists ($oInstance '__construct'))
        
call_user_func_array (array (& $oInstance '__construct') , $aArguments);
      }

    return (
$oInstance);
    }

  }



class 
TestSingleton extends Singleton
  
{
  public 
$iRandom 0;
  private 
$iSetting 0;
  
  protected function 
__construct ($iSetting 0
    {
    
# -- doppeltes Setting unterbinden
    
if (=== func_num_args ()) return;

    
$this->iRandom rand ();
    
$this->iSetting $iSetting;
    }

  public static function 
getInstance ($iSetting 0)
    {
    return (
Singleton::createInstance (__CLASS__ $iSetting));
    }


  function 
test ()
    {
    echo 
$this->iSetting;
    }

  }


// Instanz über getInstance der Klasse
$a TestSingleton::getInstance (5);
$b TestSingleton::getInstance (12);
// Instanz über Singleton Klasse
$c Singleton::createInstance ('TestSingleton' 8);

// Das würde in einem Fatal error enden
// $d = new TestSingleton (6); 
// Ebenso
// $d = clone $c;

// Zum Test, ob alle Variablen ein Objekt referenzieren
$c->iRandom '0815';

TestSingleton::getInstance ()->test ();
Singleton::createInstance ('TestSingleton')->test ();

print_r($b);
print_r($a);
print_r($c);
Wie gesagt, frisch geschrieben. Anregungen sind willkommen.
nikosch ist offline   Mit Zitat antworten
Alt 22.07.2007, 22:50  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hallo nikosch77,

Initialisierungen von singleton instanziierten Klassen sollte man tunlichst von der Erzeugung trennen, da es sonst kein echtes abstract Singleton ist. Zudem musst du bei deiner Klasse unterscheiden zwischen "create class" und "get reference", was die Implementierung umständlicher macht.

Das Thema Initialisierung habe ich in meinem Framework in das "coreObject" eingebaut. Mit der Methode "createAndInitServiceObject()" kann man sich eine Applikations-Schicht oder eine Klasse singleton instanziieren und gleichzeitig initialisieren lassen, sofern die Klasse eine init()-Methode hat. So ist transparent, dass dort eine Singlton-Instanz zurückkommt egal ob ich eine erzeugt habe oder nur eine Referenz zurückgebe inkl. Initialisierung.
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Alt 23.07.2007, 00:02  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Danke. Ich bin mir nicht sicher, ob ich Deine Hinweise vollständig verstanden habe. Meinst Du, dass man S-Instanzen prinzipiell nie initialisieren soll (wie es hier in __construct() geschieht, prizipiell aber meinetwegen auch in einer init() Methode passieren könnte)? Wenn ich Dich recht verstehe, wiederspricht es dem Prinzip der Abstraktion, weil die Singleton Klasse nicht 'wissen' kann, welche Initfunktion die implementierende Klasse bereitstellt?
Es ergibt sich bei meiner Lösung aber ein Vorteil. Da die Singleton Klasse die einzelnen S-Objekte verwaltet, weiß sie allein, welche bereits existieren. Rufe ich an verschiedenen, voneinander unabhängigen Stellen meiner Applikation die Singletonverwaltung für ein gewünschtes Objekt mit gleichen Initialisierungsparametern auf, so kann bei Instanzierung einmalig initialisiert werden und die anderen Fälle erhalten schlicht eine Referenz auf das Objekt. Ansonsten muß ich immer erst ermitteln, ob eine Instanz existiert, dann die Referenz holen und initialisieren. Ich hoffe Du kannst nachvollziehen was ich meine.

Ich habe nur die getAndInitServiceObject() Methode gefunden, ich denke Du meinst diese? Die Idee ist nicht schlecht, mein bisheriges 'Framework' besaß ein Application-Objekt, dass mir meine Singletons bereitgestellt und initialisiert hat. Na mal sehen. Die obige Lösung schien mir naheliegend, weil eine normale Klasse durch die Erweiterung mit extends Singleton und durch das Setzen des Konstruktors auf protected einfach zur Singleton konvertiert werden kann. Die bisherige Initialisierung bleibt dabei gleich, da bei Instanzierung über die createInstance() Methode bisherige Initvariablen einfach durchgereicht werden.

Zitat:
Zitat von dr.e.
Zudem musst du bei deiner Klasse unterscheiden zwischen "create class" und "get reference", was die Implementierung umständlicher macht.
Was meinst Du damit? In beiden möglichen Instanzierungsmöglichkeiten
PHP-Code:
$object Classname::getInstance (); 
bzw.
PHP-Code:
$object Singleton::createInstance ('Classname'); 
wird immer eine Referenz zurückgegeben, egal ob das Objekt frisch instanziert wurde oder bereits im Array $aUniqueInstances (bei Dir heißt das Cache) existierte.
Ich bin gespannt auf Deine Antwort. Mein Ziel ist eben eine abstrakte Umsetzung des Singleton Patterns in php5, ohne auf GLOBALS ausweichen zu müssen, wie es Dein Framework tut.
nikosch 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

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php implements, php auf variable der kindklasse zugreifen, abstrakte klasse als singleton, singleton abstrakte klasse, singleton als abstrakte klasse, php gegenstück parent, php parent instanzierte klasse, php parent zugriff auf kind, method_exists kindklassse php, zendframework eigenen controller klasse, php parent klasse ermitteln, singleton in abstrakter klasse erzeugen, php abstrakte klasse und singleton, php von parent auf child klassen zugreifen, singleton in zend framework, singelton abstrakte klasse, php parent::, parent php class, extends php gegenstück, abstrakte klasse verwendet singelton php

Alle Zeitangaben in WEZ +2. Es ist jetzt 21:26 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.