example - php constructor overload
__construct() vs SameAsClassName() para constructor en PHP (11)
¿Hay alguna ventaja de usar __construct()
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 PHP versión 4 hasta la versión 7.
Adelante compatibilidad. Siempre existe la posibilidad de que el código heredado que queda en el idioma por razones de compatibilidad con versiones anteriores se elimine en una versión futura.
Bien, han pasado unos años desde que se hizo esta pregunta, pero creo que todavía tengo que responder esta, porque las cosas han cambiado y para los lectores en el futuro quiero mantener la información actualizada.
Por lo tanto, en php-7 eliminarán la opción de crear el constructor como una función con el mismo nombre que la clase. Si aún 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 se defina un constructor PHP 4 . 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 de 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 constructores.
Además, no obtendrá un E_STRICT
en php-7 si define un método con el mismo nombre que la clase AND a __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 le recomendaría que use __construct()
, ya que tendrá menos problemas con esto en el futuro.
Creo que la razón principal es que es la convención del lenguaje. No es necesario obligar a un idioma a actuar como otra persona.
Quiero decir, en Objective-C prefijas los constructores con -init, por ejemplo. Puede hacer su propio constructor usando su nombre de clase, pero ¿por qué? ¿Hay alguna razón para usar este esquema en lugar de la convención de idioma?
En PHP 5, la ventaja sería que el rendimiento sería mejor. Primero buscará un constructor con el nombre de __construct
y, si no lo encuentra, buscará constructores con el nombre de className
. Entonces, si encuentra un constructor con el nombre __construct
, no necesita buscar un constructor con el nombre className
.
En su ejemplo, Foo::Foo
veces se denomina 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 de PHP 4 quedarán obsoletos, pero no se eliminarán 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 característica.
Estoy de acuerdo con Gizmo, la ventaja es que no tienes que cambiarle el nombre si cambias el nombre de tu clase. SECO.
Del mismo modo, si tiene una clase para niños, puede llamar
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 construcción al padre.
Parece una cosa pequeña, pero perder el cambio del nombre de la llamada del constructor a las clases de sus padres podría crear errores sutiles (y no tan sutiles).
Por ejemplo, si inserta una clase en su heirachy, pero se olvidó de cambiar las llamadas al constructor, podría comenzar a llamar constructores de abuelos en lugar de padres. Esto a menudo podría causar resultados indeseables que podrían ser difíciles de detectar.
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 nombre de espacio ya no serán tratados como constructores. Este cambio no afecta a las clases sin nombre de espacio.
Hoy, la respuesta aceptada es obsoleta.
Renombrar 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 nueva. A veces (como usar Reflection o estructura de dependencia compleja) puede ser imposible sin una refactorización radical. Y esta es la complejidad accidental que desea evitar. Es por eso que los espacios de nombres se introdujeron en PHP. Java, C ++ o C # no usan __construct
, usan named constructor y 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 con nombre de espacio ya no serán tratados como constructores. Este cambio no afecta a las clases sin nombre de espacio .
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 en desuso (PHP 5.5 hoy). Sin embargo, no puede predecir que su clase no se utilizará en el espacio de nombres, por __construct
tanto __construct
debe ser __construct
.
Aclaración sobre la mala práctica mencionada anteriormente (para Dennis)
En algún lugar de tu código podrías usar ReflectionClass::getName() ; cuando cambie el nombre de la clase, debe recordar dónde utilizó Reflection y comprobar si el resultado de getName()
sigue siendo coherente en su aplicación. Cuanto más necesite recordar algo específico, más probabilidades hay de que se olvide algo que da como resultado errores en la aplicación.
Los padres no pueden tener control sobre todas las clases del mundo que dependen de ellos. Si allow_url_include está habilitado, algún otro sitio web podría estar 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 puede copiarse y agruparse en otro código.
No hay ninguna razón para cambiar el nombre de clase:
- si el nombre de la clase entra en conflicto, use espacios de nombres
- si la responsabilidad de la clase cambia, deriva alguna otra clase en su lugar
En las clases de PHP en el espacio de nombres, el método con el mismo nombre debe evitarse de todos modos: intuitivamente debe producir un objeto creado 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 problema con __construct constructores en PHP. Pero no fue la idea más inteligente alterar los constructores nombrados.
La mejor ventaja de usar __contruct()
lugar de ClassName()
es cuando se extienden las clases. Es mucho más fácil llamar a parent::__construct()
lugar de parent::ClassName()
, ya que es reutilizable entre las clases y el elemento principal se puede cambiar fácilmente.
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.
Si hay métodos __construct y SameAsClassName, se ejecutará __construct, se omitirá el método SameAsClassName.
__construct
se introdujo en PHP5. Es la forma en que se supone que debes hacerlo ahora. Sin embargo, no conozco ninguna ventaja per se.
Del manual de PHP:
Para compatibilidad con versiones anteriores, si PHP 5 no puede encontrar una función __construct () para una clase determinada, buscará la función de constructor de estilo anterior, por el nombre de la clase. Efectivamente, significa que el único caso que tendría problemas de compatibilidad es si la clase tenía un método llamado __construct () que se usó para semántica diferente
Si está en PHP5, le recomendaría usar __construct
para evitar que PHP se vea en otro lado.