2012-10-24 8 views
10

php 5.3+metodo call class php da metodo statico all'interno della stessa classe ma non istanziato

Ci scusiamo per la lunga domanda, ma voglio impararlo completamente.

So che non è possibile chiamare un metodo non statico della stessa classe all'interno di un metodo statico, senza che la classe sia istanziata come oggetto.

Dalla ricerca su SO, ho trovato alcuni approcci interessanti, ma mi chiedo come ogni approccio influisce sull'ambiente di codice.

Le mie domande sono al di sotto:

ho potuto creare un'istanza della classe come un oggetto all'interno del metodo statico, per ottenere l'accesso al metodo non statico

static function showPeople() 
{ // instantiate as object 
    $person = New Person(); 
    // call class method 
    $people_data = $this->data_all_get(); 
} 

Q1 - quali problemi potrebbe questa causa ? nella mia situazione, la classe non ha un costruttore quindi nessun altro metodo di classe o vars sarà influenzato dall'istanza. Questo nuovo oggetto occuperebbe solo un piccolo spazio in memoria durante l'esecuzione dello script? Non sembra troppo male ...


l'altra opzione sarebbe quella di convertire il metodo "data_all_get" in un metodo statico, in modo che possa essere chiamato dall'interno del metodo "showPeople" statica, cioè

self::showPeople() 

il metodo "data_all_get" viene utilizzato da altri metodi della classe quando viene istanziato come oggetto, per impostare il valore della variabile privata, per ridurre i viaggi nel database, se è già impostato. So che probabilmente potrebbe far parte di una funzione di costruzione, ma non ho mai avuto bisogno che questo oggetto "Persona" fosse istanziato più di una volta per richiesta di script php, la classe è principalmente usata per raggruppare le funzioni e le vars insieme per l'organizzazione.

Q2 - quali sono le implicazioni nel rendere "data_all_get" in un metodo statico? ci sono? se il metodo era statico, ma imposta il valore della var $ people_array privata (che non è statica), penso che var possa essere aggiornato o sovrascritto se l'oggetto ha mai avuto bisogno di essere istanziato una seconda volta in un singolo richiesta di script, corretta? Inoltre, poiché la proprietà non è statica, altri metodi della classe possono accedervi.

Q3 - Potrei chiamare il metodo statico "data_all_get" tutte le volte che volevo senza "rompere nulla" (una domanda caricata IK).

Q4 - Utilizza semplicemente memoria aggiuntiva ogni volta che viene chiamato il metodo statico?

Grazie

+0

Non capisco davvero perché showPeople come lo hai elencato qui è una funzione statica. Il codice che hai incollato sopra sembra un codice OO piuttosto standard e, come hai detto se puoi semplicemente istanziare la classe in ogni caso, non c'è motivo di farlo staticamente. Penso che il modo migliore di pensare ai metodi statici sia come funzioni autonome, racchiuse in una classe. (Funziona comunque per me). Da quello che stai descrivendo, basta rilasciare la chiamata statica, ma se hai bisogno di usarla, penso che il codice che hai incollato sopra dovrebbe andare bene (istanziando la classe). – DaOgre

+1

grazie per il feedback. sto rendendo il metodo statico in modo che possa essere chiamato da altre aree/percorsi dell'applicazione senza dover prima istanziare un oggetto (come un file include in un mondo pre-oop). Ho fatto ulteriori ricerche e test e attualmente mi sto impegnando a rendere statiche anche le proprietà dei membri e gli altri metodi di classe che devono impostare tali proprietà statiche, quindi questa classe statica può chiamarle. ora sto lavorando ... –

+0

aggiornamento: ho refactored e reso statiche le proprietà dei membri, e ho reso statiche le funzioni getter & setter in modo che possano essere chiamate sia dal metodo membro statico che dai metodi di classe, e funziona. ma vorrei ancora qualche commento e suggerimento sulle mie 4 domande elencate sopra, grazie. –

risposta

11
class Person 
{ 
    private static $people_array; 

    static public function data_all_get() 
    { 
     self::$people_array = //DBStuff 
    } 

    static public function showPeople() 
    { 
     $people_data = self::data_all_get(); 
    } 
} 

A pochi note, alcune forse ovvio. 1) Poiché non si restituisce nulla, ovviamente il codice sopra riportato non funzionerà. Non c'è niente di sbagliato, per esempio, con il codice qui sopra. In risposta al tuo Q1 tutto ciò che hai fatto è stato preso una coppia di chiamate di funzione usando una variabile globale e incapsulate all'interno di una classe.Vorrei sconsigliare a volte usarlo come una lezione istanziata e talvolta non farlo, poiché renderà il tuo codice finale meno leggibile e più difficile da capire per le persone quando lo stanno osservando.

Se si è preoccupati di eseguire l'istanziazione di questo più di una volta, si potrebbe voler guardare il modello di progettazione singleton, ma in generale se si prevede di istanziare la classe a un certo punto vorrei riesaminare il motivo per cui si ' ri chiamandoli staticamente in primo luogo. Non c'è niente di sbagliato in questo, per dire, a parte il fatto che "mi sembra sbagliato" per me.

Q2) L'unica implicazione di rendere data_all_get in un array statico è quindi fare riferimento a una proprietà statica, che a sua volta significa che questa proprietà sarà inaccessibile se istanziata. Inoltre, stai perdendo la capacità di istanziare più versioni di questa classe (se ciò è importante) e in pratica trasformare people_array in una variabile globale. Questo non è necessariamente negativo, ma senza sapere cosa sta facendo il resto della tua funzionalità è difficile dire quali sono le implicazioni.

Q3) L'unico problema che lo esegue più volte è A) che cancella qualsiasi cosa sia presente nell'array di persone e B) Chiamate di DB multiple. Senza vedere quale altro codice sta andando su queste domande è più o meno impossibile rispondere.

Q4) La memoria per un metodo delle dimensioni di ciò che è elencato qui è trascurabile al punto di non valere la pena di parlare. La preoccupazione arriva con la chiamata DB stessa e il numero di righe a cui ci si trova

Infine, è un po 'strano visto che questo codice è stato scritto ora, poiché showPeople fa esattamente la stessa cosa di data_all_get. Probabilmente vorresti scrivere una logica all'interno di showPeople per vedere se $ people_array è vuoto o no, e se è così, esegui data_all_get e se no, restituisci people_array. Ciò eviterà letture DB aggiuntive. Se avete intenzione di leggere il DB ogni volta in ogni caso, allora potreste anche avere data_all_get restituire $ people_array, nel qual caso nessuno di questi deve essere all'interno di una classe, e può semplicemente essere una chiamata di funzione che restituisce ciò che trova nel db.

Problemi correlati