Domanda

C'è qualche vantaggio nell'usare __construct () invece del nome della classe per un costruttore in PHP?

Esempio ( __construct ):

class Foo {
    function __construct(){
        //do stuff
    }
}

Esempio (denominato):

class Foo {
    function Foo(){
        //do stuff
    }
}

Avere il metodo __construct (primo esempio) è possibile dal PHP 5.

Avere un metodo con lo stesso nome della classe come costruttore (secondo esempio) è possibile dalla versione 4 di PHP alla versione 7.

È stato utile?

Soluzione

Sono d'accordo con gizmo, il vantaggio è che non è necessario rinominarlo se si rinomina la classe. SECCO.

Allo stesso modo, se hai una classe figlio puoi chiamare

parent::__construct()

per chiamare il costruttore principale. Se più in basso si cambia la classe da cui la classe figlio eredita, non è necessario modificare la chiamata di costruzione al genitore.

Sembra una cosa piccola, ma mancare di cambiare il nome della chiamata del costruttore nelle classi dei tuoi genitori potrebbe creare bug sottili (e non così sottili).

Ad esempio, se hai inserito una classe nella tua erede, ma hai dimenticato di cambiare le chiamate del costruttore, potresti iniziare a chiamare i costruttori di nonni anziché i genitori. Ciò potrebbe spesso causare risultati indesiderati che potrebbero essere difficili da notare.

Nota anche che

  

A partire da PHP 5.3.3, i metodi con lo stesso nome dell'ultimo elemento di un nome di classe con spaziatura dei nomi non saranno più trattati come costruttore. Questa modifica non influisce sulle classi non spaziate.

Fonte: http://php.net/manual/en/language. oop5.decon.php

Altri suggerimenti

__construct è stato introdotto in PHP5. È il modo in cui dovresti farlo ora. Tuttavia, non sono a conoscenza di vantaggi di per sé.

Dal manuale di PHP:

Per compatibilità con le versioni precedenti, se PHP 5 non riesce a trovare una funzione __construct () per una data classe, cercherà la funzione di costruzione vecchio stile, con il nome della classe. In effetti, significa che l'unico caso che avrebbe problemi di compatibilità è se la classe avesse un metodo chiamato __construct () che è stato usato per diverse semantiche

Se sei su PHP5, ti consiglio di usare __construct per evitare che PHP appaia altrove.

Il vantaggio principale che vedo per __construct è che non è necessario rinominare il costruttore se si modifica il nome della classe.

Oggi la risposta accettata è obsoleta.

Rinominare le lezioni è una cattiva pratica: devi ricordare cosa e dove rinominare ogni volta che aggiorni alla versione più recente. A volte (come usare Reflection o una struttura di dipendenza complessa) può essere impossibile senza un refactoring radicale. E questa è complessità accidentale che vuoi evitare. Ecco perché spazi dei nomi sono stati introdotti in PHP. Java, C ++ o C # non usano __construct , usano il nome costruttore e non c'è nessun problema con loro.

  

A partire da PHP 5.3.3, i metodi con lo stesso nome dell'ultimo elemento di un nome classe spaziato non saranno più trattati come costruttore. Questa modifica non influisce sulle classi senza spaziatura .

Esempio

namespace Foo;
class Test {
  var $a = 3;

  function Test($a) {
    $this->a = $a;
  }

  function getA() {
    return $this->a;
  }
}

$test = new Test(4);
echo $test->getA(); // 3, Test is not a constructor, just ordinary function

Nota che i costruttori nominati non sono deprecati (PHP 5.5 oggi). Tuttavia, non puoi prevedere che la tua classe non verrà utilizzata nello spazio dei nomi, pertanto pertanto __construct dovrebbe essere preferibile.

Chiarimento sulla cattiva pratica sopra menzionata (per Dennis)

In qualche parte del codice è possibile utilizzare ReflectionClass :: getName () ; quando rinomini la classe, devi ricordare dove hai usato Reflection e verificare se il risultato getName () è ancora coerente nella tua app. Più devi ricordare qualcosa di specifico, più è probabile che venga dimenticato qualcosa che provoca bug nell'app.

I genitori non possono avere il controllo su tutte le classi del mondo che dipendono da loro. Se allow_url_include è abilitato, alcuni altri Web potrebbero utilizzare il classe dal server, che potrebbe bloccarsi se si rinomina una classe. È ancora peggio nei linguaggi compilati menzionati sopra: la libreria può essere copiata e raggruppata in altro codice.

Non c'è motivo per rinominare la classe:

  • se il nome della classe è in conflitto, utilizzare gli spazi dei nomi
  • se la responsabilità della classe cambia, deriva invece un'altra classe

Nelle classi PHP nello spazio dei nomi, il metodo con lo stesso nome dovrebbe essere comunque evitato: intuitivamente dovrebbe produrre un oggetto creato la classe; se fa qualcos'altro, perché dargli lo stesso nome? Dovrebbe essere un costruttore e nient'altro. Il problema principale è che il comportamento di tale metodo dipende dall'utilizzo dello spazio dei nomi.

Non ci sono problemi con i costruttori __construct in PHP. Ma non è stata l'idea più intelligente di modificare i costruttori nominati.

Il miglior vantaggio dell'uso di __contruct () invece di ClassName () è quando si estendono le classi. È molto più semplice chiamare parent :: __ construct () anziché parent :: ClassName () , poiché è riutilizzabile tra le classi e il genitore può essere facilmente modificato.

Nel tuo esempio Foo :: Foo viene talvolta chiamato PHP 4 o costruttore vecchio stile perché deriva dai giorni di PHP 4:

class Foo {
    // PHP 4 constructor
    function Foo(){
        //do stuff
    }
}

I costruttori di PHP 4 saranno deprecati ma non rimossi in PHP 7. Non saranno più essere considerato costruttori in qualsiasi situazione in PHP 8. La compatibilità futura è sicuramente un grande motivo per non utilizzare questa funzione.

In PHP 5 il vantaggio sarebbe che le prestazioni sarebbero migliori. Cercherà innanzitutto un costruttore con il nome di __construct e, se non lo trova, cercherà i costruttori con il nome di className . Quindi se trova un costruttore con il nome __construct non è necessario cercare un costruttore con il nome className .

Beh, sono passati alcuni anni da quando questa domanda è stata posta, ma penso di dover rispondere ancora a questo, perché le cose sono cambiate e per i lettori in futuro voglio mantenere le informazioni aggiornate!

Quindi in php-7 rimuoveranno l'opzione per creare il costruttore come una funzione con lo stesso nome della classe. Se lo fai ancora otterrai un E_DEPRECATED .

Puoi leggere ulteriori informazioni su questa proposta (la proposta è accettata) qui:   https://wiki.php.net/rfc/remove_php4_constructors

E una citazione da lì:

  

PHP 7 emetterà E_DEPRECATED ogni volta che viene definito un costruttore PHP 4 . Quando il nome del metodo corrisponde al nome della classe, la classe non si trova in uno spazio dei nomi e un costruttore PHP 5 (__construct) non è presente, verrà emesso un E_DEPRECATED. PHP 8 smetterà di emettere E_DEPRECATED e i metodi non saranno riconosciuti come costruttori.

Inoltre non otterrai un E_STRICT in php-7 se definisci un metodo con lo stesso nome della classe E un __construct () .

Puoi vederlo anche qui:

  

PHP 7 inoltre smetterà di emettere E_STRICT quando è presente un metodo con lo stesso nome della classe e __construct.

Quindi ti consiglio di usare __construct () , dato che avrai meno problemi con questo in futuro.

Compatibilità diretta. C'è sempre la possibilità che il codice legacy lasciato nella lingua per motivi di compatibilità con le versioni precedenti venga rimosso in una versione futura.

Se sono presenti metodi __construct e SameAsClassName, verrà eseguito __construct, il metodo SameAsClassName verrà ignorato.

Penso che il motivo principale sia la convenzione linguistica. Non è necessario forzare una lingua per agire come qualcun altro.

Voglio dire, in Objective-C prefissi i costruttori con -init, per esempio. Puoi creare il tuo costruttore usando il nome della tua classe, ma perché? Ci sono dei motivi per usare questo schema invece della convenzione linguistica?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top