2011-11-22 15 views
11

Sono un po 'confuso su come funzionano i costruttori in PHP.Costruttori PHP e funzioni statiche

Ho una classe con un costruttore che viene chiamato quando istanzio un nuovo oggetto.

$foo = new Foo($args); 

__construct($params) è chiamato nella classe Foo ed esegue il codice di inizializzazione appropriato.

Tuttavia, quando uso la classe per chiamare una funzione statica, il costruttore viene chiamato di nuovo.

$bar = Foo::some_function(); //runs the constructor from Foo 

Questo fa sì che il costruttore per eseguire, eseguire il codice oggetto di inizializzazione che intendevo solo quando si crea un nuovo oggetto Foo.

Mi manca il punto su come funzionano i costruttori? O esiste un modo per impedire l'esecuzione di __construct() quando uso la classe per effettuare chiamate di funzioni statiche?

Devo utilizzare una funzione "fabbrica" ​​per eseguire l'inizializzazione dell'oggetto? Se è così, qual è il punto del costruttore, allora?

:: MODIFICA :: Ho un modulo in cui gli utenti possono caricare le foto su un album (create_photo.php) e un'area in cui possono visualizzare l'album (view_photos.php). Al modulo inviare:

$photo = new Photo($_FILES['photo'], $_POST['arg1'], ect..); 

Il costruttore di foto crea e salva la foto. Tuttavia in view_photo.php, quando chiamo:

$photo = Photo::find_by_id($_POST['id']) //user-defined function to query database 

Ciò sta causando il costruttore di foto da eseguire!

+8

Questo non può essere giusto. Si prega di fornire il codice completo in cui il costruttore viene chiamato da una chiamata statica! – mAu

+0

Mostra il tuo codice reale. Quello che stai scrivendo non sembra corretto. –

+0

Come si presenta il costruttore, da quale comportamento si conclude che funziona? – markus

risposta

16

Non vedo nulla che replichi la tua domanda.

See Demo: http://codepad.org/h2TMPYUV

Codice:

class Foo { 
    function __construct(){ 
     echo 'hi!'; 
    } 
    static function bar(){ 
     return 'there'; 
    } 
} 

echo Foo::bar(); //output: "there" 
+2

Non dovrebbe essere '__construct()'? Il risultato è lo stesso anche se ... – jeroen

+0

@jeroen corretto^_^nice catch – Neal

6

Assunzione PHP 5.x

obiettivi diversi, diverse percorso

  1. creare una nuova istanza di una classe (oggetto)

    class myClassA 
    { 
        public $lv; 
    
        public function __construct($par) 
        { 
         echo "Inside the constructor\n"; 
         $this->lv = $par; 
        } 
    } 
    
    $a = new myClassA(11); 
    $b = new myClassA(63); 
    

    perché creiamo un nuovo oggetto chiamate PHP:

    __construct($par);

    del nuovo oggetto, quindi:

    $a->lv == 11 
    
    $b->lv == 63 
    
  2. utilizzare una funzione di una classe

    class myClassB 
    { 
        public static $sv; 
    
        public static function psf($par) 
        { 
         self::$sv = $par; 
        } 
    } 
    
    myClassB::psf("Hello!"); 
    $rf = &myClassB::$sv; 
    myClassB::psf("Hi."); 
    

    ora $rf == "Hi."

    funzione o variabiles mosto definito statica essere utilizzati da ::, non viene creato alcun oggetto che chiama "psf", la "variabile di classe" sv ha onl y 1 istanza all'interno della classe.

  3. utilizzare un Singleton creato da una fabbrica (myClassA è al di sopra)

    class myClassC 
    { 
    
        private static $singleton; 
    
        public static function getInstance($par){ 
    
         if(is_null(self::$singleton)){ 
    
          self::$singleton = new myClassA($par); 
    
         } 
    
         return self::$singleton; 
    
        } 
    
    } 
    
    $g = myClassC::getInstance("gino"); 
    echo "got G\n"; 
    
    $p = myClassC::getInstance("pino"); 
    echo "got P\n"; 
    

Utilizzando la fabbrica (getInstance) la prima volta che si costruisce un nuovo oggetto che ha $ par insieme a gino.

Utilizzando la fabbrica la seconda volta $ singleton ha già un valore che restituiamo. Nessun nuovo oggetto creato (no __costruct viene chiamato, meno memoria & viene utilizzata la cpu).

Il valore, naturalmente, è un oggetto instanceof myClassA e non dimenticare:

myClassC::$singleton->lv == "gino"

Prestare attenzione al single:

What is so bad about singletons?

http://www.youtube.com/watch?v=-FRm3VPhseI

By mio ans non voglio promuovere/declassare singleton. Semplicemente dalle parole nella domanda, ho fatto questo calcolo:

"statico" + "__ costrutto" = "singleton"!

+0

dovresti aver aggiunto una dichiarazione di non responsabilità riguardo le classi ansatiche del singleton: http://stackoverflow.com/questions/137975/what-is-so-bad -about-singletons e http://www.youtube.com/watch?v=-FRm3VPhseI –

+0

solo per chiarire $ g = myClassC :: getInstance ("gino"); e quindi $ p = myClassC :: getInstance ("pino"); , $ g-> lv e $ p-> lv valori sono uguali = "gino". non gine e pino, perché il costruttore esegue solo una volta! – Miguel

1

Ecco il mio soluzione:

ho messo metodo construct() in classe statica. Si noti, è diverso da __construct() che uso nelle classi regolari.

Ogni classe è nel proprio file, quindi carico il file al primo utilizzo della classe.Questo mi dà l'evento del primo uso della classe.

spl_autoload_register(function($class) { 

    include_once './' . $class . '.php'; 

    if (method_exists($class, 'construct')) { 
     $class::construct(); 
    } 
});