2009-07-16 7 views
10

Vorrei sapere se è accettabile/preferibile utilizzare self :: method() e parent :: method() quando si lavora nelle classi php.

È possibile utilizzare $ this-> method() ma $ this-> può anche fare riferimento a una variabile di classe, a una variabile di classe parent o a un metodo della classe padre. Non c'è alcuna ambiguità in se stessi ::

È self :: deprezzato e/o ci sono avvertimenti o contro usare questo stile?

Comprendo che self :: e parent :: si riferiscono a un'istanza statica della classe, ma in kohana, a meno che non si definisca specificamente un metodo come statico, non sembra esserci differenza.

Grazie.

Aggiunto un esempio: Assumendo questa applicazione memorizza forum da più siti web ...

class Forum_Controller extends Controller { 

    function __construct() 
    { 
     parent::__construct(); 
    } 

    function index() 
    { 
     echo self::categories(); 
    } 

/* 
* get a list of categories from a specific site. 
*/ 
    private function categories() 
    { 
     $db = new Database; 
     $categories = $db->query(" 
      SELECT * FROM 
      forum_categories 
      WHERE fk_site = '$this->site_id' 
     "); 
     $view = new View('categories_view'); 
     $view->categories = $categories; 
     return $view; 
    } 

} 

Questo esempio funziona in kohana con segnalazione degli errori impostato: error_reporting (E_ALL & ~ E_STRICT);

$ this-> site_id è definito nella classe Controller_Core principale (una libreria in kohana).

Per quanto ne so, $ non dovrebbe essere disponibile poiché sto chiamando self :: categories() in modo statico, ma è solo quando definisco le categorie() come statico che genera un errore .

Ma come ho detto preferisco di gran lunga usare l'auto: perché da una prospettiva di leggibilità, so esattamente dove dovrebbe essere questa funzione, piuttosto che usare $ ciò che causa ambiguità, per me è così.

+1

Il motivo per cui questo codice funziona è perché non si è mai riferimento a un $ tale istanza dell'oggetto nella chiamata staticamente metodo di categorie. – null

risposta

6

I controlli non sono statici in Kohana, sebbene possano contenere variabili/metodi o costanti membri statici.

self:: è un modo veloce di scrivere ClassName:: cioè

class Animal 
{ 
    public static $arms = 0; 
} 

class Dog extends Animal 
{ 
    public static $leg = 0; 
    const NAME = 'dog'; 

    public static function bark() 
    { 
     echo 'Woof'; 
    } 
} 

Per chiamare funzioni statiche o ottenere costanti da una classe usiamo l'operatore di risoluzione dell'ambito ::. Le funzioni statiche sono per classe non per oggetto.Dire :: fa riferimento a istanze statiche di una classe è errato, è solo un modo per accedere ai metodi statici - non esiste un'istanza di oggetto che abbia questi metodi.

così:

Dog::bark(), 
Dog::$leg, 
Dog::NAME, 

possiamo anche usare

Animal::$arms 

All'interno del Cane di classe che possiamo usare self:: e parent:: in modo che non abbiamo bisogno di digitare il nome completo della classe (come potrebbe essere molto lunghi!)

In risposta alla tua domanda però: No - self:: non è deprecato e non è una cattiva pratica usarlo. Il motivo per cui non viene utilizzato nel core kohana è per una ragione molto diversa ... (estensioni di classe trasparenti con eval leggi sotto per maggiori informazioni ...).

P.S chiamando i metodi non statici è staticamente sbagliato e non deve essere allowed- se si imposta error_reporting(E_ALL | E_STRICT) (come si dovrebbe durante lo sviluppo), vedrete un errore risuscitato.

In sostanza ciò che accade è:

Core ha un file chiamato:

class Controller_Core { 
    public function someMethod(){} 
} 

Si crea:

// We can use someMethod of Controller_Core 
Index_Controller extends Controller {} 

Questo è veramente estendendo Controller_CoreMENO aver creato mio_controllore .php che sarebbe class Controller extends Controller_Core.

//MY_Controller.php 
class Controller extends Controller_Core 
{ 
     // overloads Controller_Core::someMethod without us having to change the core file 
     public function someMethod(){} 
} 
+0

Grazie per aver dedicato del tempo per spiegare questo. È molto utile Capisco ora cosa intendi per "Le funzioni statiche sono per classe non per oggetto". Leggerò la documentazione fornita da Benlumley, ma sono ancora sconcertato dal fatto che il mio codice funzioni ancora: ho aggiunto un codice di esempio alla mia domanda, per favore date un'occhiata. Grazie ancora. – superjadex12

0

Penso che self :: sia usato generalmente per funzioni e proprietà statiche.

Io uso Kohana e forse i controller sono resi statici.

16

C'è una differenza.

$this fa riferimento a un'istanza di un oggetto.

parent e self vengono utilizzati per chiamare i metodi staticamente.

This page of PHP's manual lo spiega in modo più dettagliato di quello che ho tempo di scrivere al momento. Il primo esempio in particolare dovrebbe aiutare a evidenziare alcune delle differenze. Ti incoraggio a copiare incolla il primo esempio e confonderlo, poiché ritengo che sia un concetto importante da prendere in considerazione se non conosci già la differenza.

+0

Grazie per la risposta. Il collegamento alla documentazione è molto utile. Non sono riuscito a trovare le parole giuste per trovarlo, altrimenti. – superjadex12

+0

genitore non è (solo) utilizzato per chiamare il metodo staticamente. Se viene chiamato da un contesto Object, chiamerà la funzione nella classe genitore con il contesto dell'oggetto. –

0

non ho potuto aggiungere un commento (a quanto pare non ho il rappresentante richiesto!)

class Forum_Controller extends Controller { 

public function __construct() 
{ 
    parent::__construct(); 
} 

public function index() 
{ 
    echo self::categories(); 
} 

/* 
* get a list of categories from a specific site. 
*/ 
private static function categories() 
{ 
    $db = new Database; 

    // You cannot use $this in a static function, because static functions are per class 
    // and not per object it doesnt know what $this is :) (make private static $site_id and use self::$site_id) if this is what you want 

    $categories = $db->query(" 
      SELECT * FROM 
      forum_categories 
      WHERE fk_site = '$this->site_id' 
    "); 
    $view = new View('categories_view'); 
    $view->categories = $categories; 
    return $view; 
} 

}

Come ho detto, si dovrebbe usare error_reporting (E_ALL | E_STRICT) ; (Cambiarlo nel file kohana)

chiamando categorie di funzioni private() funziona staticamente causa di un bug in PHP, non si dovrebbe essere in grado di farlo :)

0

un'altra cosa da notare dal modo in cui è che questo non è un buon progetto MVC per creare funzioni di controller statico che restituiscano elenchi di categorie.

I controllori sono per la gestione delle richieste, i modelli sono per la gestione dei dati (che è ciò che è) e le viste sono per la visualizzazione.

fare un modello!

class Category_Model extends Model 
{ 
     public function categories($site_id) 
     { 
      $categories = $this->db->from('forum_categories')->where('fk_site',$site_id)->get(); 

       return new View('categories_view', array('categories' => $categories)); 
     } 
} 

...

$cat = new Category_Model; 

echo $cat->categories(1); 
0

ho utilizzare esclusivamente self :: solo per le variabili statiche e funzione di membro static