construct () vs SameAsClassName () para constructor en PHP


¿Hay alguna ventaja en usar __construct() en lugar del nombre de la clase para un constructor en PHP?

Ejemplo (__construct):

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

Ejemplo (nombrado):

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

Tener el método __construct (primer ejemplo) es posible desde PHP 5.

Tener un método con el mismo nombre que la clase como constructor (segundo ejemplo) es posible desde la versión 4 de PHP hasta la versión 7.

Author: hakre, 2008-10-20

11 answers

Estoy de acuerdo con gizmo, la ventaja es que no tiene que cambiarle el nombre si cambia el nombre de su clase. SECO.

Del mismo modo, si tiene una clase hija, puede llamar a

parent::__construct()

Para llamar al constructor padre. Si más adelante en la pista cambia la clase de la que hereda la clase hija, no tiene que cambiar la llamada de construct al padre.

Parece una cosa pequeña, pero falta cambiar el nombre de la llamada del constructor a sus clases de padres podría crear sutil (y no tan sutil) insectos.

Por ejemplo, si insertó una clase en su heirachy, pero olvidó cambiar las llamadas al constructor, podría comenzar a llamar a constructores de abuelos en lugar de padres. Esto a menudo podría causar resultados indeseables que podrían ser difíciles de notar.

También tenga en cuenta que

A partir de PHP 5.3.3, los métodos con el mismo nombre que el último elemento de un nombre de clase con espacio de nombres ya no serán tratados como constructores. Este cambio no afecta clases sin espacio de nombres.

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

 66
Author: Bazman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-06 08:53:16

__construct se introdujo en PHP5. Es la forma en que se supone que debes hacerlo ahora. No estoy al tanto de ningunaventaja per se, sin embargo.

Del manual de PHP:

Para compatibilidad con versiones anteriores, si PHP 5 no puede encontrar una función __construct() para una clase dada, buscará la función constructora de estilo antiguo, por el nombre de la clase. Efectivamente, significa que el único caso que tendría problemas de compatibilidad es si la clase tuviera un método llamado _ _ construct () que se utiliza para diferentes semánticas

Si estás en PHP5 te recomendaría usar __construct para evitar que PHP busque en otra parte.

 19
Author: Paolo Bergantino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-20 05:57:11

La principal ventaja que veo para __construct, es que no tienes que cambiar el nombre de tu constructor si cambias el nombre de tu clase.

 15
Author: gizmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-20 06:01:11

Hoy en día, la respuesta aceptada es obsoleta.

Cambiar el nombre de las clases es una mala práctica: debe recordar qué y dónde cambiar el nombre cada vez que actualice a una versión más reciente. A veces (como usar Reflexión o estructura de dependencia compleja) puede ser imposible sin refactorización radical. Y esto es complejidad accidental que desea evitar. Es por eso que espacios de nombres fueron introducidos en PHP. Java, C++ o C # no usan __construct, usan constructor con nombre y hay no hay problema con ellos.

A partir de PHP 5.3.3, los métodos con el mismo nombre que el último elemento de un nombre de clase namespaced ya no serán tratados como constructores. Este cambio no afecta a las clases sin espacio de nombres.

Ejemplo

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

Tenga en cuenta que los constructores con nombre no están obsoletos (PHP 5.5 hoy en día). Sin embargo, no puede predecir que su clase no se utilizará en el espacio de nombres, por lo tanto __construct debería ser preffered.

Aclaración sobre la mala práctica mencionada anteriormente (para Dennis)

En algún lugar de tu código puedes usar ReflectionClass::getName(); cuando cambies el nombre de la clase, necesitas recordar dónde usaste Reflection y comprobar si el resultado getName() sigue siendo consistente en tu app. Cuanto más necesitas recordar algo específico, más probable es que algo se olvide, lo que resulta en errores en la aplicación.

Los padres no pueden tener control sobre todo las clases en el mundo que depende de ellos. Si allow_url_include está habilitado, es posible que otra web esté utilizando la clase de su servidor, que puede bloquearse si cambia el nombre de alguna clase. Es aún peor en los lenguajes compilados mencionados anteriormente: la biblioteca se puede copiar y empaquetar en otro código.

No hay razón para cambiar el nombre de la clase:

  • si el nombre de la clase entra en conflicto, use espacios de nombres
  • si la responsabilidad de clase cambia, derive alguna otra clase en su lugar

En las clases PHP en el espacio de nombres, el método con el mismo nombre debe evitarse de todos modos: intuitivamente debe producir un objeto creado por la clase; si hace algo más, ¿por qué darle el mismo nombre? Debería ser un constructor y nada más. El problema principal es que el comportamiento de dicho método depende del uso del espacio de nombres.

No hay ningún problema con los constructores __construct en PHP. Pero no fue la idea más inteligente alterar a los constructores nombrados.

 10
Author: Jan Turoň,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-25 11:44:48

La mejor ventaja de usar __contruct() en lugar de ClassName() es cuando se extienden clases. Es mucho más fácil llamar a parent::__construct() en lugar de parent::ClassName(), ya que es reutilizable entre clases y el padre se puede cambiar fácilmente.

 7
Author: Ryan McCue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-20 09:30:19

En su ejemplo Foo::Foo a veces se llama PHP 4 o constructor de estilo antiguo porque proviene de los días de PHP 4:

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

Los constructores PHP 4 serán obsoletos pero no eliminados en PHP 7. Ya no serán considerados como constructores en ninguna situación en PHP 8. La compatibilidad futura es definitivamente una gran razón para no usar esta función.

 7
Author: Levi Morrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-13 03:12:21

En PHP 5 la ventaja sería que el rendimiento sería mejor. Buscará un constructor por el nombre de __construct primero y si no lo encuentra, buscará constructores por el nombre de className. Así que si encuentra un constructor por el nombre __construct no es necesario buscar un constructor por el nombre className.

 3
Author: Steven Oxley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-20 06:00:04

Bueno, han pasado algunos años desde que se hizo esta pregunta, pero creo que todavía tengo que responder a esta, porque las cosas han cambiado y para los lectores en el futuro quiero mantener la información actualizada!


Así que en php-7 eliminarán la opción de crear el constructor como una función con el mismo nombre que la clase. Si todavía lo haces obtendrás un E_DEPRECATED.

Puede leer más sobre esta propuesta (la propuesta es aceptada) aquí: https://wiki.php.net/rfc/remove_php4_constructors

Y una cita de allí:

PHP 7 emitirá E_DEPRECATED cada vez que un PHP 4 constructor se define. Cuando el nombre del método coincide con el nombre de la clase, la clase no está en un espacio de nombres, y un constructor PHP 5 (__construct) no está presente, entonces se emitirá un E_DEPRECATED. PHP 8 dejará de emitir E_DEPRECATED y los métodos no serán reconocidos como constructor.

Tampoco obtendrá un E_STRICT en php-7 si define un método con el mismo nombre que la clase Y un __construct().

Puedes ver esto también aquí:

PHP 7 también dejará de emitir E_STRICT cuando esté presente un método con el mismo nombre que la clase, así como __construct.


Así que te recomendaría usar __construct(), ya que tendrás menos problemas con esto en el futuro.

 3
Author: Rizier123,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-29 15:07:01

Compatibilidad hacia adelante. Siempre existe la posibilidad de que el código heredado que queda en el lenguaje por razones de compatibilidad con versiones anteriores se elimine en una versión futura.

 2
Author: Jeremy Privett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-10-20 09:14:50

Si hay métodos __construct y el método SameAsClassName entonces se ejecutará __construct, el método SameAsClassName se saltará.

 1
Author: phvish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-06 06:35:54

Creo que la razón principal es que es la convención del lenguaje. No necesitas forzar a un idioma a actuar como otra persona.

Quiero decir, en Objective-C se antepone a los constructores con-init, por ejemplo. Puedes hacer tu propio constructor usando el nombre de tu clase, pero ¿por qué? ¿Hay alguna razón para utilizar este esquema en lugar de la convención de lenguaje?

 0
Author: Leonardo Molina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-06 00:44:25