2011-09-16 13 views
9

¿Hay alguna razón para establecer un valor para las variables en el constructor de una clase en lugar de cuando las declaras? Me doy cuenta de que no puedes pasar datos a las variables si tratas de establecerlos cuando se declaran, pero ¿qué pasa con las cosas que siempre serán las mismas (supongo que siempre será un reclamo difícil de hacer)?¿Por qué establecer variables dentro de la construcción de una clase de PHP cuando puede establecerlas cuando se declaran?

class variables_set_outside_constructor 
{ 
    private $admin_name = 'jeff'; 
    private $current_working_directory = get_cwd(); 

    function __construct() {} 
} 

en contraposición a esto:

class variables_set_inside_constructor 
{ 
    private $admin_name; 
    private $current_working_directory; 

    function __construct() 
    { 
     $this->admin_name = 'jeff'; 
     $this->current_working_directory = get_cwd(); 
    } 
} 

¿Cuáles son las ventajas y desventajas de los valores de los ajustes en el constructor frente cuando se declaran? Tengo curiosidad acerca de cualquier aspecto independiente del idioma también.

+3

No estoy seguro de entender lo que está pidiendo. ¿Podría darnos un ejemplo de cada una de las dos técnicas que está tratando de comparar? –

+1

Estoy agradecido porque soy un programador muy experimentado que de alguna manera nunca aprendió por qué sería malo declarar cosas fuera de un constructor. Estoy sorprendido de que tanta gente bailara alrededor de esta pregunta solo para contarte cosas irrelevantes sobre tu ejemplo. Pero un mejor ejemplo puede haber sido valores predeterminados. Como un juego - nivel int = 1; entonces el constructor puede anular esto, pero al menos siempre tendrá un valor predeterminado. Incluso después de leer esto, todavía no estoy seguro de una respuesta oficial. Supongo que continuaré declarando en clase y luego completando en constructo. –

+0

Es posible que desee volver a verificar su segundo ejemplo. (En realidad, compruébalos ambos - 'clase X() {}' es sintaxis inválida. Pero ...) El valor por defecto de una propiedad tiene que ser literal (o tal vez una constante), lo último que escuché. – cHao

Respuesta

2

Primera razón: reutilización.

Segundo motivo: Las credenciales para la conexión de su base de datos no pertenecen a una clase de base de datos, esto debe ser manejado en su aplicación. Su clase solo debe saber cómo aceptarlos y usarlos, no definirlos.

Un buen ejemplo de caso es tener otra información de inicio de sesión en su development machine y luego en su staging/live machine. Esto le muestra al instante el problema de declarar en el constructor.


no me di cuenta lo que el intento fue hasta su comentario. Ya no estoy acostumbrado a ver var, supongo. Afortunadamente, no era el único. Por supuesto, declarar así es imposible.

+0

Tercer motivo: la inicialización del miembro de la clase solo funciona con constantes, no con expresiones. 'new mysqli ('host', 'name', 'pass', 'directory');' nunca funcionaría. – hakre

3

Tiene un error en su pregunta. Esto no funciona en una clase:

class foo 
{ 
    var $mysqli = new mysqli('host', 'name', 'pass', 'directory'); 
} 

Prueba el Demo para ver lo que no funciona aquí.

Así que tal vez una (!) Razones para escribir

class foo 
{ 
    var $mysqli; 
    public function __construct() 
    { 
     $this->mysqli = new mysqli('host', 'name', 'pass', 'directory'); 
    } 
} 

es porque no hay alternativa a la misma (entre las dos alternativas que se ofrecen en su cuestión sólo, naturalmente. Esta es una práctica mala horrorful para hacerlo sin un diseño delicado basado en la inyección de dependencia y otras abstracciones de diseño de alto nivel, o más preciso: esto está haciendo mysqli una dependencia de foo - incluyendo la configuración de la base de datos).

Junto a esto, por favor no utilice var, utilice private, protected o public lugar.

+0

@downvoter: Por favor, comparta sus ideas. – hakre

0

Para facilitar el acceso. Al declararlos todos en una ubicación central, puede ver una lista de todas las variables.

No es un gran problema si los declaras cuando se crea si estás en un proyecto en solitario. Si está trabajando con equipos, tiene más sentido seguir algunos estándares para no confundirse.

0

Aunque no es flexible, la definición de variables cuando se declara que puede ser útil si va a utilizar una clase sin crear una instancia por alguna razón:

class MyClass { 
    public $MyVar = 'hello'; 

    function MyFunction() { 
    return self::MyVar; 
    } 
} 

echo MyClass::MyFunction(); 
2

Usted puede encontrar this article on Java object initializers a ser de algún interés.

Aunque muchos de los conceptos en el artículo son específicos de Java y no es relevante para PHP, es posible encontrar algunos de estos puntos interesantes:

  • Antes de utilizar una propiedad en una clase, generalmente quieren debe inicializarse con algún valor (en PHP, esto no es un requisito, pero en la práctica rara vez veo violada esta directriz). Si tiene varios constructores, entonces debe inicializar la propiedad en cada constructor, lo que significa que habrá mucha copia y pegado. (PHP also has multiple contructors:)

  • En las subclases de Java, solo se llama al constructor padre "no-arg" de forma predeterminada, lo que significa que no se puede garantizar que una subclase llame al constructor "correcto". En PHP, el problema se agrava porque no se puede garantizar que la subclase llame al constructor de la clase padre. Inicializar las propiedades directamente en la declaración de la clase principal asegura que esas propiedades siempre comiencen con la inicialización, incluso si el constructor de la subclase no las inicializa.

0

puede ayudar a recuperar el registro de la base de datos una vez y volver a utilizar los registros. como he hecho con la biblioteca de inicio de sesión de tankauth.

class Welcome extends CI_Controller{ 
    public $id; 
    function __construct(){ 
     parent::__construct(); 
     $this->id = $this->tank_auth->get_user_id(); 
    } 
function index(){ $this->MyModel->get_user($this->id);} 
function admin(){ $this->MyModel->get_admin($this->id);} 
function profile(){ $this->MyModel->get_profile($this->id);} 
} 
0

Personalmente, me gustan las variables declaradas dentro del constructor debido a que es más fácil de gestionar. Si tengo una clase con toneladas y toneladas de métodos, entonces sería un dolor en el ** encontrar dónde se declara la variable o incluso peor, digamos que estamos recibiendo una solicitud POST, ¿qué pasaría si me olvido de desinfectar y validar esta publicación. Inyección de SQL ... Si tiene todas las solicitudes de servidor dentro del constructor, puede encontrarlas fácilmente, por ejemplo, crear un método que desinfecte en función de lo que está esperando y luego estará protegido contra esos ataques.

ejemplo:

<?php 
    Class Example extends Core_Controllers 
    { 
     private $_var = null; 

     public function __construct(){ 

       if(isset($_POST['number'])): 
       $this->_var = $this->santizeNumber($_POST['number']); 
       else: 
       $this->_var = "Not Declared Yet"; 
       endif; 

      $this->methodToCall(); 
     } 
     } 


     public function sanitizeNumber($number){ 
       return filter_var($number, FILTER_SANITIZE_NUM_INT); 
     } 

     public function methodToCall(){ 
      echo $this->_var; 
     } 
Cuestiones relacionadas