2008-10-20 16 views

Respuesta

64

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 usted tiene una clase hija puede llamar

parent::__construct() 

a 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, métodos con el mismo nombre que el último elemento de un nombre de clase de espacio de nombres ya no serán tratados como constructor. Este cambio no afecta a las clases sin nombre de espacio.

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

+10

El estilo del constructor PHP 4.x quedará obsoleto en PHP 7.0 y se eliminará en la siguiente versión principal. http://php.net/manual/de/migration70.deprecated.php#migration70.deprecated.php4-constructors – SimonSimCity

18

__construct se introdujo en PHP5. Es la forma en que se supone que debes hacerlo ahora. Sin embargo, no conozco ninguna de las ventajas per se.

Desde el manual de PHP:

Para compatibilidad hacia atrás, si PHP 5 no puede encontrar una función __construct() para una clase dada, se buscará la función constructora de estilo antiguo, con 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 recomendaría usar __construct para evitar que PHP se vea en otra parte.

3

En PHP 5, la ventaja sería que el rendimiento sería mejor. Primero buscará un constructor con el nombre __construct y, si no lo encuentra, buscará constructores con el nombre className. Por lo tanto, si encuentra un constructor con el nombre __construct, no necesita buscar un constructor con el nombre className.

14

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.

2

Compatibilidad hacia adelante. 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.

7

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

0

Creo que la razón principal es que es la convención del idioma. No necesita forzar un idioma para actuar como otra persona.

Quiero decir, en Objective-C prefija 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?

10

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. Algunas veces (como usar Reflection o una estructura de dependencia compleja) puede ser imposible sin una refactorización radical. Y esto es accidental complexity que desea evitar. Es por eso que namespaces se introdujeron en PHP. Java, C++ o C# no usan __construct, usan el constructor con nombre y no hay problema con ellos.

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

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 el nombre constructores no están en desuso (PHP 5.5 en la actualidad). Sin embargo, no puede predecir que su clase no se utilizará en el espacio de nombres, , por lo tanto, se debe preferir__construct.

Aclaración de la mala práctica se mencionó anteriormente (Dennis)

En algún lugar de su código se puede utilizar 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 ellas. Si allow_url_include está habilitado, algún otro sitio web podría estar usando 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 por la que para cambiar el nombre de clase:

  • si los conflictos de nombre de la clase, el uso de espacios de nombres
  • si los cambios de responsabilidad clase, derivar alguna otra clase en 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 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 de construcciones __ en PHP. Pero no fue la idea más inteligente alterar los constructores nombrados.

+0

¿Puede por favor reescribir el párrafo 2 para mayor claridad? (uno que comienza con "Renombrar ...". Estoy perdido en por qué es una mala práctica cambiar el nombre de las clases, y por qué no hay problemas con Java, C, C++, y cómo es relevante para esta pregunta. PHP también debería usar el constructor nombrado como Java, C, C++ o ¿hay problemas? ¿Cuáles son los problemas? – Dennis

+1

@Dennis Ver mi respuesta actualizada. Es relevante para la respuesta aceptada, porque Bazman dio un error al renombrar la clase: no lo hizo En el momento en que proporcioné mi respuesta, el punto sobre el espacio de nombres en su respuesta, lo copió de mi respuesta más tarde. Ahora se lleva el crédito, pero no importa, no afecta la información en sí y a nadie le importa. –

1

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

2

Bueno, 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.


Así que en php-7 que pueden eliminar 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 (se acepta la propuesta) aquí: https://wiki.php.net/rfc/remove_php4_constructors

y una cita a partir de ahí:

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 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.

También usted no conseguirá un E_STRICT en php-7 si se define un método con el mismo nombre que la clase y una __construct().

Esto se puede ver 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.


por lo que recomiendo que use __construct(), ya que tendrá menos problemas con esto en el futuro.

+0

¡Gracias por la actualización! – Newtang

+0

@Newtang Solo un biiit tarde: D – Rizier123

7

En su ejemplo Foo::Foo a veces se llama un PHP 4 o constructor de estilo antiguo, ya que viene desde los días de PHP 4:

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

PHP 4 constructors will be deprecated but not removed en PHP 7. Serán ya no puede considerarse como constructores en cualquier situación en PHP 8. La compatibilidad futura es definitivamente una gran razón para no usar esta característica.

Cuestiones relacionadas