Pagina 1 di 5 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 48

Discussione: Singleton esteso

  1. #1

    Singleton esteso

    Ho questo problema... ho bisogno di utilizzare __CLASS__ da una classe estesa:

    esempio di questo è il Singleton.
    Vorrei infatti stanziare una classe Singleton ed estenderla alle classi che devono essere di tipo singleton.
    codice:
    <?php
    
    class Singleton {
    	private static $instance;
    
    	private function __construct() {}
    
    	public static function getInstance() {
    		if(!isset(self::$instance)) {
    			$object = __CLASS__;
    			self::$instance = new $object();
    		}
    		return self::$instance;
    	}
    }
    
    ?>
    Naturalmente non funziona... poiché __CLASS__ contiene "Singleton" e non il nome della classe che la estende.
    come posso fare?

    non vorrei ripetere il codice del Singleton per ogni classe.
    grazie
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  2. #2
    Utente di HTML.it L'avatar di Razorblade
    Registrato dal
    Feb 2002
    Messaggi
    1,308
    Ciao,
    spulciando tra vari framework, posso dirti che una possibile soluzione al tuo problema sia creare una classe statica per istanziare le classi che vuoi che siano singleton.
    Ad esempio

    Codice PHP:
    $miaClasse Loader::load('MiaClasse'); 
    La classe statica al suo interno avrà un array che conterrà le istanze degli oggetti singleton ( se precedentemente richiamati, altrimenti è vuoto ).
    Ovviamente bisognerà fornire a questa classe un array contenente tutte le classi singleton valide e questo forse può dare fastidio.


    Il risultato che vuoi raggiungere tu senza dover cambiare rotta ( ovvero estendere Singleton ) può essere raggiunto implementando questo codice presente nel costruttore della classe Configurable del framework 'Taste':

    Codice PHP:
       $this->sections = array();
            
        
    $class get_class($this);
        
    $this->sections[] = $class;
            
         while(
    $class get_parent_class($class))
            
    $this->sections[] = $class

    L'ultimo indice dell'array 'sections' dovrebbe essere il nome della classe che cerchi.
    Fammi sapere.

    Ciao

  3. #3
    Diciamo che più o meno funziona... o perlomeno non funziona come dovrebbe
    Codice PHP:
    <?php
    class Singleton {
        private static 
    $instance;

        private function 
    __construct() {}

        public function 
    getInstance() {
            if(!isset(
    self::$instance)) {
                
    $object get_class($this);             /* linea 10 */
                
    self::$instance = new $object();      /* linea 11 */
            
    }
            return 
    self::$instance;
        }
    }
    ?>
    Codice PHP:
    <?php
    class IniConfig extends Singleton {
        public function 
    prova() {
            return 
    "testo di prova";
        }
    }
    ?>
    ammettiamo di dover fare

    $i = IniConfig::getInstance();
    print "<h1>".$i->prova()."</h1>";

    mi restituisce l'errore:

    Notice: Undefined variable: this in C:\Programmi\EasyPHP 2.0b1\www\Wipy\includes\system\Singleton.php on line 10

    Fatal error: Class name must be a valid object or a string in C:\Programmi\EasyPHP 2.0b1\www\Wipy\includes\system\Singleton.php on line 11


    se io modificassi la linea 10 mettendo
    $object = __CLASS__;

    mi restituirebbe l'errore

    Fatal error: Call to undefined method Singleton:rova() in C:\Programmi\EasyPHP 2.0b1\www\Wipy\includes\_header.php on line 13

    perché in effetti __CLASS__ è la stringa "Singleton" e non "IniConfig" come invece io vorrei che fosse...

    se il metodo prova fosse nativo di Singleton allora tutto funzionerebbe... ma naturalmente a me questo non serve.

    come risolvo la situazione?
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  4. #4
    Utente di HTML.it L'avatar di Razorblade
    Registrato dal
    Feb 2002
    Messaggi
    1,308
    Ciao,
    ci sono diversi errori:
    il primo è l'utilizzo della variabile $this. Il metodo getInstance() è chiamato staticamente, quindi $this riferito all'oggetto non esiste.
    get_class inoltre è valido solo se gli passi un oggetto.
    Inoltre non hai implementato tutto il codice che ho scritto, anche questa parte è importante perchè recuperà la classe radice

    Codice PHP:
     while($class get_parent_class($class))
            
    $this->sections[] = $class

  5. #5
    si ok... ma considera che quel codice non posso metterlo nei costruttori delle classi che ereditano Singleton... vorrei che stesse tutto dentro il Singleton

    in ogni caso l'ho provato, e l'ultimo valore è la classe radice... quindi "Singleton"... a me invece serve "IniConfig" per poter utilizzare il metodo prova()
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  6. #6
    Utente di HTML.it L'avatar di Razorblade
    Registrato dal
    Feb 2002
    Messaggi
    1,308
    Ciao,
    penso che quello che tu voglia fare attualmente non sia fattibile perchè php fino al 5.2 non supporta il late state binding http://php.html.it/articoli/leggi/25...rogrammazione/ .

    Quindi alla seguente chiamata statica

    Codice PHP:
    IniConfig::getInstance() 
    il valore restituito da __CLASS__ sarà sempre Singleton e mai IniConfig, almeno fino a quando non si potrà usare static:: .
    Ovviamente si accettano conferme o smentite.
    Ciao

  7. #7
    Il problema non è solo di __CLASS__
    anche self è riferito alla classe dove il metodo è dichiarato, ergo in questo empio, self::$_instance sarà sempre una sola per tutti, e non è utilizzabile come Singleton:
    codice:
    <?php
    class Singleton {
        public static  $_instance;
        public static function getInstance() {
            self::$_instance = rand();
        }
    }
    
    class A extends Singleton {}
    
    class B extends Singleton {}
    
    A::getInstance();
    echo Singleton::$_instance.'
    ';
    B::getInstance();
    echo Singleton::$_instance.'
    ';
    echo A::$_instance.'
    ';
    echo B::$_instance.'
    ';
    ?>
    [edit]
    ovviamente se ridichiari $_instance come static di ogni classe il problema non sussiste.
    Ma se devi fare questo, tanto vale attendere lazy binding, oppure usare alternative più semplici, tipo quella del Singleton Factory postata sopra
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  8. #8
    P.S. magari questo interessa:
    http://webreflection.blogspot.com/20...t-factory.html

    Implicit Factory + Singleton design pattern per PHP
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  9. #9
    @Mackey
    Dai anche un occhio al design pattern
    registry





    Dopo le levate di capo prese
    in questo pattern istanzio la classe
    una volta e la passo per aggregazione
    dove serve


    Patterns are not perfect in all situations and the Registry pattern is no exception. It helps simplify our source code but there are issues to watch out for. For one thing, the use of a Singleton Registry replaces numerous Singletons but still has a global nature. This is warning enough to be careful using the Registry.

    Insomma non lo si deve mettere da tutte le parti
    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  10. #10
    @andr3a

    Ero un po che non soffrivo di emicrania

    __autofactory


    ciò i compiti


    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.