2009-07-31 12 views
5

Ho una pagina include.php che carico all'inizio di ogni pagina del mio sito web. Mentre sviluppo il sito web, il numero di classi che sto usando sta crescendo. così finisco con qualcosa di simile:prestazioni di caricamento classi php e l'uso di 'extends'

$db = new DB($config); 
$login = new Login($db, $config); 
$form = new Form($db, $config); 

E l'elenco potrebbe continuare all'infinito. Ho due domande su questa pratica:

In primo luogo, considerando che potrei non usare una classe in una determinata pagina (potrei non avere un $ form su ogni singola pagina), quanto conta davvero, le prestazioni- saggio, per caricare questa classe ogni volta che viene caricata una determinata pagina?

In secondo luogo, potresti aver notato che sto passando l'istanza di classe $ db a tutte le altre classi, oltre a una variabile $ config. Nel codice php di ogni classe, faccio qualcosa di simile:

public $db; 
public $config; 

public function __construct($db, $config, $smarty){ 
    $this->db = $db; 
    $this->config = $config; 
} 

poi i metodi della classe, rivolgo i file di database e di configurazione con 'questo' in quanto tale:

public function myfunction(){ 
    $this->db; 
    $this->config; 
} 

Quando dovrebbe Io uso 'extends' piuttosto che passare $ db alla classe, assumendo che ogni classe usi il db? Passare $ db ad ogni classe fa male in alcun modo in termini di prestazioni?

Grazie!

risposta

7

Quando devo usare 'estende', piuttosto che passare $ db alla classe, assumendo ogni classe utilizza il db?

Quando ha senso - e solo quando lo fa!

di avere almeno due cose da considerare:

  • "class A extends B" tipo di mezzi "class A **is a** B"
    • più chiaramente, una Car è un MotorVehicule; a MotorVehicule è un Vehicule; a Bus è un MotorVehicule; una bicicletta è un Vehicule
    • tuttavia, un Ball non è un Vehicule
    • Nel tuo caso, un Form non è sicuramente un DataBase! Né è un Login
  • In PHP, una classe può solo extenduno classe
    • Non si può avere qualcosa di essere sia un Vehicule ed un Animal
    • Ma un Carè unMotorVehicule , che, a sua volta, è unVehicule:-)

Nel caso di un oggetto di database (nel tuo caso, è più di una connessione ad un DB), mosts delle vostre classi saranno non si "essere" una connessione al database. Quindi, non dovrebbero estendere quella classe.

Tuttavia, essi si utilizza una connessione DB (un Form "ha un" connessione DB); quindi, dovrebbero avere una proprietà che rappresenta quella connessione DB. Questo è quello che stai facendo.


Invece di passare $db per ogni costruttore, è possibile utilizzare

  • sia il modello di Singleton disegno
  • o il modello di progettazione Registro
  • o qualche tipo di variabile globale, ma questo è quasi il stesso ... solo peggio (non OOP e tutto il resto)!

Ma passare l'oggetto $db è ottimo per l'unit test, gli oggetti fittizi e tutto ciò che ...
penso che potrebbe essere considerato come il design Iniezione modello Dipendenza, btw (non sono sicuro, ma sembra che)


sul caricamento sacco di classi, altre persone hanno dato risposte:

  • Usa caricamento automatico se si può
  • Utilizzare una cache codice operativo, come APC, se potete

Entrambi questi sono grandi suggerimenti che si dovrebbe prendere in considerazione ;-)


Un'ultima cosa:

Does passando $ db per ogni classe male in alcun modo in termini di prestazioni?

Forse fa un po po ; ma, onestamente, tranne se sei google e hai milioni di utenti ... a chi importa?

Se si stanno eseguendo un paio di query DB, quelle impiegheranno molto tempo, rispetto al passaggio di un altro parametro a una dozzina di metodi!
Così, la piccola quantità di tempo utilizzato paremeters passando probabilmente può essere trascurato :-)

+0

Grande e completo! Grazie mille. –

+0

Prego :-) Buon divertimento! –

+1

Estendere le lezioni è stato per me un piccolo mistero per un po 'di tempo, questa è una spiegazione grandiosa e semplice che mi ha reso immediatamente chiaro quando usarlo. – Kokos

4

Hai provato qualcosa del genere?

function __autoload($class_name) { 
require_once("includes/php/class." . $class_name . ".php"); 
} 

Quindi carica solo il nome classe quando viene rilevato il nome classe. (Cambia il percorso per adattarlo alle tue classi php ... le mie sono come class.Object.php, con il nome della classe "Object").

+1

aggiungere a questa cosa jeyoung detto: si dovrebbe davvero caricare solo quello che ti serve * quando * avete bisogno presente. Ci sono ancora alcune domande senza risposta in questo post (quando usare extends), che potrebbe essere meglio estratta in nuove domande SO. –

+0

Inserirò questo codice nel mio file include o nelle mie classi? Tuttavia, non troverà sempre la variabile, poiché istanziato la classe subito dopo aver caricato il file? Grazie! –

+0

Inseriresti questo codice nel tuo header.php (che è incluso in tutti i tuoi file). Puoi spiegare cosa intendi istanziando la classe subito dopo aver caricato il file? – Dirk

1

Perché non includere solo i file che devono essere inclusi? Inoltre, prova ad istanziare solo quegli oggetti di cui hai bisogno dove ti servono. Così com'è, il tuo includes.php sta facendo un sacco di istanze che potresti non aver bisogno di tutto il tempo.

Se $db viene passato come riferimento, non dovrebbe influire sulle prestazioni. (Io non so molto di PHP5, ma con PHP4 c'era un concetto di riferimento con la '&' modificatore.)

+0

Mi sono sempre chiesto, cosa fa il simbolo e commerciale (&) in PHP? –

+2

Il & fornisce un riferimento a una variabile. In PHP5 non dovresti mai usarlo come metodo per migliorare le prestazioni (PHP fa copia-su-scrittura). Anche in PHP5 le variabili oggetto sono già riferimenti all'oggetto, quindi gli oggetti non vengono copiati a meno che non si usi 'clone'. –

2

Se caricamento e l'analisi dei file di script diventa un collo di bottiglia è possibile utilizzare una cache bytecode come apc per accelerare questa parte del ciclo di vita.

+0

Che cosa fa esattamente apc? –

+0

Quando PHP carica uno script, deve analizzare i contenuti in opcode. apc memorizza questi opcode così la prossima volta non è necessario eseguire il parser. Se disabiliti il ​​controllo stat, è anche possibile evitare (relativamente lento) l'accesso ai file. – VolkerK

1

Non sono sicuro di come si desidera utilizzare l'ereditarietà ('extends') qui. Potresti usarlo per definire i due campi $db e $config, ma altrimenti non cambierebbe molto.

Inoltre, potrebbe limitare l'utente quando effettivamente si desidera ereditare qualcosa utile da un'altra classe.

A seconda del progetto, è possibile prendere in considerazione l'idea di rendere $config globale. C'è una situazione in cui è attiva più di una configurazione allo stesso tempo? Probabilmente non sarebbe una buona idea introdurre una variabile globale $db. È concepibile che potresti avere bisogno di più di una connessione al database allo stesso tempo, ad esempio.

+0

L'unica ragione per cui non uso $ config come globale è perché ho sentito che non è sicuro. Il nome utente e la password del mio database sono memorizzati nel file di configurazione. Non c'è un vero problema di sicurezza con la dichiarazione delle variabili globali? –

Problemi correlati