2009-07-18 12 views
6

Attualmente sto creando un sistema di blog, che spero di trasformare in un CMS completo in futuro.Come evitare di utilizzare oggetti globali PHP?

Ci sono due classi/oggetti che sarebbero utili per avere accesso globale a (la connessione al database mysqli e una classe personalizzata che controlla se un utente ha effettuato l'accesso).

Sto cercando un modo per farlo senza utilizzare oggetti globali e, se possibile, non passare gli oggetti a ciascuna funzione ogni volta che vengono chiamati.

risposta

13

Gli oggetti possono essere statici, quindi è possibile accedervi ovunque. Esempio:

myClass::myFunction(); 

Che funzionerà ovunque nella sceneggiatura. Si potrebbe comunque voler leggere su classi statiche e possibilmente usare una classe Singleton per creare una classe regolare all'interno di un oggetto statico che possa essere utilizzata ovunque.

Expanded

Penso che quello che si sta cercando di fare è molto simile a quello che faccio con la mia classe DB.

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
} 

quello che succede è che si ottiene dopo la connessione, utilizzando $ oggetto = myClass :: get_connection(), sarete in grado di fare qualsiasi cosa funzioni regolarmente.

$object = myClass::get_connection(); 
$object->runClass(); 

Expanded

Una volta fatto che le dichiarazioni statiche, basta chiamare get_connection e assegnare il valore restituito a una variabile. Quindi il resto delle funzioni può avere lo stesso comportamento di una classe chiamata con $ class = new myClass (perché è quello che abbiamo fatto). Tutto quello che stai facendo è memorizzare la variabile di classe all'interno di una classe statica.

class myClass 
{ 
    static $class = false; 
    static function get_connection() 
    { 
     if(self::$class == false) 
     { 
      self::$class = new myClass; 
     } 
     return self::$class; 
    } 
    // Then create regular class functions. 
    public function is_logged_in() 
    { 
     // This will work 
     $this->test = "Hi"; 
     echo $this->test; 
    } 
} 

$object = myClass::get_connection(); 
$object->is_logged_in(); 
+0

Ciao, grazie per la tua risposta, è possibile salvare le variabili nelle classi statiche. cioè la funzione di chiamata per verificare se l'utente è loggato e quindi accedere a questa variabile più volte più tardi nella pagina? –

+2

Sì, per una classe statica fare la stessa cosa che ho fatto per dichiarare la variabile $ class. L'unica cosa è che devi 'dichiarare ogni variabile che usi. –

+1

Ma il codice che ti ho dato ti permette di usare qualsiasi classe regolare, bene, regolarmente. La parte statica ti dà semplicemente la classe, invece di globalizzarla. Modificherò per mostrare un po 'di più. –

1

Bene, se si dispone già di un oggetto con il quale si fa riferimento al sistema di blog, è possibile comporre questi oggetti in quella, in modo che siano $blog->db() e $blog->auth() o qualsiasi altra cosa.

+0

Potrei, ma gli oggetti dovranno anche accedere al di fuori della classe blog. –

8

È possibile passare gli oggetti globali globali nel costruttore.

3

Recentemente ho rinnovato il mio framework in preparazione della seconda versione del CMS della nostra azienda. I undid una quantità enorme delle cose che ho fatto statico al fine di sostituirli con oggetti normali. Così facendo, ho creato un'enorme quantità di flessibilità che un tempo si basava su di me per passare attraverso l'hacking nei file principali. Ora utilizzo solo i costrutti statici quando l'unica alternativa è rappresentata dalle funzioni globali, che è solo correlata alla funzionalità di base di basso livello.

Mostrerò alcune righe del mio file bootstrap.php (tutte le mie richieste vengono inviate tramite quel file, ma puoi ottenere lo stesso risultato includendolo nella parte superiore di ogni file) per mostrarti ciò che intendo. Questa è una versione piuttosto pesante di quello che probabilmente useresti nella tua situazione, ma si spera che l'idea sia utile. (Questo è tutto leggermente modificato.)

//bootstrap.php 

... 

// CONSTRUCT APPLICATION 

{  
    $Database = new Databases\Mysql(
     Constant::get('DATABASE_HOST'), 
     Constant::get('DATABASE_USER'), 
     Constant::get('DATABASE_PASSWORD'), 
     Constant::get('DATABASE_SCHEMA') 
    ); 

    $Registry  = new Collections\Registry; 
    $Loader  = new Loaders\Base; 
    $Debugger  = new Debuggers\Dummy; // Debuggers\Console to log debugging info to JavaScript console 

    $Application = new Applications\Base($Database, $Registry, $Loader, $Debugger); 
} 

... 

Come potete vedere, ho tutti i tipi di opzioni per creare il mio oggetto applicazione, che posso fornito come argomento nel costruttore ad altri oggetti per dare loro l'accesso a queste necessità "globali".

L'oggetto del database è autoesplicativo. L'oggetto del Registro di sistema funge da contenitore per l'oggetto che potrei voler accedere altrove nell'applicazione. Il caricatore funge da utilità per caricare altre risorse come i file modello. E il debugger è lì per gestire l'output di debug.

Posso, ad esempio, modificare la classe di database che istanziato e, voilà, ho una connessione a un database SQLite. Posso modificare la classe del debugger (come indicato) e ora tutte le mie informazioni di debug verranno registrate nella mia console JavaScript.

Ok, ora torna al problema. Come concedi ad altri oggetti l'accesso a tutto questo? Basta passarlo in un argomento al costruttore.

// still bootstrap.php 

... 

// DISPATCH APPLICATION 

{ 
    $Router = new Routers\Http($Application); 
    $Router->routeUri($_SERVER['REQUEST_URI']); 
} 

... 

Non solo, ma anche il mio router (o qualsiasi altro oggetto che costruisco con esso) è più flessibile. Ora posso solo istanziare il mio oggetto applicativo in modo diverso, e il mio router si comporterà in modo diverso di conseguenza.

Problemi correlati