__construct () vs SameAsClassName () per constructor in PHP

C'è qualche vantaggio nell'usare __construct() posto del nome della class per un constructor in PHP?

esempio:

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

O

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

Sono d'accordo con gizmo, il vantaggio è che non devi rinominarlo se rinomina la tua class. ASCIUTTO.

Allo stesso modo, se hai una lezione per bambini puoi call

 parent::__construct() 

call il constructor genitore. Se in fondo alla traccia si modifica la class dalla quale eredita la class figlia, non è necessario modificare la chiamata di costrutto al genitore.

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

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

Si noti inoltre che

A partire da PHP 5.3.3, i methods con lo stesso nome dell'ultimo elemento di un nome di class con spazio dei nomi non saranno più trattati come constructor. Questa modifica non ha effetto sulle classi non assegnate ai nomi.

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

__construct stato introdotto in PHP5. È il modo in cui dovresti farlo ora. Non sono a conoscenza di alcun vantaggio di per sé, però.

Dal manuale PHP:

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

Se sei su PHP5 ti consiglio di usare __construct per evitare di far guardare PHP altrove.

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

Oggi la risposta accettata è obsoleta.

La ridenominazione delle classi è una ctriggers pratica: è necessario ricordare cosa e where rinominare each volta che si esegue l'aggiornamento alla versione più recente. A volte (come usare Reflection o una struttura di dipendenza complessa) può essere imansible senza un refactoring radicale. E questa è una complessità accidentale che vuoi evitare. Ecco perché gli spazi dei nomi sono stati introdotti in PHP. Java, C ++ o C # non usano __construct , usano il constructor nominato e non ci sono problemi con loro.

A partire da PHP 5.3.3, i methods con lo stesso nome dell'ultimo elemento di un nome di class con spazio dei nomi non saranno più trattati come constructor. Questa modifica non ha effetto sulle classi non assegnate ai nomi .

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 con nome non sono deprecati (PHP 5.5 oggi). Tuttavia, non puoi prevedere che la tua class non verrà utilizzata nello spazio dei nomi, pertanto __construct dovrebbe essere prefferato.

Chiarimento sulle cattive pratiche di cui sopra (per Dennis)

Da qualche parte nel tuo codice puoi usare ReflectionClass :: getName () ; quando si rinomina la class, è necessario ricordare where si è utilizzato Reflection e verificare se il risultato di getName() è ancora coerente nella propria app. Più hai bisogno di ricordare qualcosa di specifico, più è probabile che qualcosa venga dimenticato e ciò provochi dei bug nell'app.

I genitori non possono avere il controllo di tutte le classi del mondo che dipendono da loro. Se allow_url_include è abilitato, un altro web potrebbe utilizzare la class dal tuo server, che potrebbe bloccarsi se si rinomina qualche class. È ancora peggio nelle lingue compilate sopra menzionate: la libreria può essere copiata e inserita in un altro codice.

Non c'è alcun motivo per rinominare la class:

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

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

Non c'è alcun problema con i costruttori __construct in PHP. Ma non era l'idea più intelligente di alterare i costruttori nominati.

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

Nel tuo esempio Foo::Foo è talvolta chiamato constructor di PHP 4 o vecchio stile perché proviene dai giorni di PHP 4:

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

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

In PHP 5 il vantaggio sarebbe che le performance sarebbero migliori. Prima cercherà un constructor con il nome di __construct e, se non lo trova, cercherà i costruttori con il nome di className . Quindi, se trova un constructor con il nome __construct , non ha bisogno di cercare un constructor con il nome className .

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.

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

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

Puoi leggere di più 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 each volta che viene definito un constructor PHP 4 . Quando il nome del metodo corrisponde al nome della class, la class non è in uno spazio dei nomi e un constructor PHP 5 (__construct) non è presente, quindi verrà emesso E_DEPRECATED. PHP 8 smetterà di emettere E_DEPRECATED ei methods non saranno riconosciuti come costruttori.

Inoltre non si otterrà un E_STRICT in php-7 se si definisce un metodo con lo stesso nome della class AND a __construct() .

Puoi vederlo anche qui:

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

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

Se sono presenti methods __construct e SameAsClassName, allora verrà eseguito __construct, il metodo SameAsClassName verrà saltato.

Penso che la ragione principale sia quella della convenzione linguistica. Non è necessario forzare una lingua per comportrsi come qualcun altro.

Voglio dire, in Objective-C si prefissa i costruttori con -init, per esempio. Puoi build il tuo constructor usando il nome della tua class, ma perché? Ci sono dei motivi per usare questo schema al posto della convenzione linguistica?