2012-04-06 34 views
5

Básicamente, estoy creando dos clases en las que una clase, en este caso clase A, ejecuta una función en otra clase, en este caso clase B, para obtener información de la base de datos.Clase Constructor interfiriendo con otra clase

Sin embargo, cuando el B_runtime() realmente llama a la base de datos obtengo el error Cannot access protected property A::$db.

Lo que no entiendo es que a pesar de que tengo dos __construct 's en ambas clases de la declaración DOP está siendo muy persistente en el uso de la conexión a la base de la clase A.

Estoy seguro que esto tiene algo que hacer con el hecho de que estoy ejecutando el B_runtime() desde la clase A porque esto no ocurre si lo llamo desde fuera de la clase A.

Sé que puedo simplemente cambiar el protected $db; en la clase A a una variable pública Sin embargo, tengo mucha curiosidad sobre cómo puedo solucionar esto.

ob_start(); 
include('/config.php'); 
ob_end_clean(); 

$A = new A($db); 
$B = new B($db); 

echo $A->A_runtime(); 

class A{ 
    protected $db; 
    public function __construct($db){ 
     $this->db = $db; 
    } 
    public function A_runtime(){ 
     return B::B_runtime();  
    } 
} 

class B{ 
    protected $db; 
    public function __construct($db){ 
     $this->db = $db; 
    } 
    public function B_runtime(){ 
     $preparedStatement = $this->db->prepare('SELECT * FROM z_mod_html WHERE ModuleLink = :moduleid LIMIT 1'); 
     $preparedStatement->execute(array(':moduleid' => '1')); 
     $rows = $preparedStatement->fetchAll(); 
     return $rows[0]['HTML']; 
    } 
} 

Lo siento por la larga cantidad de código - si alguien tiene alguna idea o sugerencia sería muy apreciada. Gracias.

Respuesta

3

Puede pasar la instancia de B al método. De esta manera también definir la dependencia de su método en la clase B.

$A = new A($db); 
$B = new B($db); 

echo $A->A_runtime($B); 

class A{ 
    //... 
    public function A_runtime($instance){ 
     return $instance -> B_runtime();  
    } 
} 

Incluso puede utilizar type hinting en PHP 5 para indicar que usted está esperando una instancia de la clase B no:

public function A_runtime(B $instance){ 
+0

Yea respuesta perfecta, sin embargo, hay una manera que yo puedo hacer esto con dos constructores como lo estoy haciendo ahora? – SineCosine

+0

@SineCosine Puede mantener todos sus constructores. Acabo de poner una marca '// ...' donde está el constructor, todo sigue igual. Solo cambia el método ('A_runtime') y la forma en que lo llamas. – kapa

+0

Oh, lo extrañé por completo. Gracias, no sabía que podrías esto. – SineCosine

3

Oy .

primero, está llamando a un método no estático como método estático.

B::B_runtime(); 

sólo debe utilizarse de esta manera si B_runtime se declara como un método estático

static public function B_runtime(){ 

en segundo lugar, su clase tiene una dependencia externa que generalmente se considera no es bueno. una clase solo debe confiar en lo que se le da, no en los globales. esto se llama principio de inversión de dependencia. si una clase depende de algo, deberías darle esta dependencia a través de un argumento, y aún mejor, utilizar la sugerencia de tipo para asegurarte de que la dependencia tenga los métodos que esperas.

public function A_runtime(B $object_b){ 

Para llevar esto un paso más allá, también debe utilizar resúmenes o interfaces para el tipo de alusión en lugar de clases concretas. De esta forma, puedes cambiar B con una versión diferente de B si alguna vez es necesario.

interface BInterface { 
    public function B_runtime(); 
} 

continuación

public function A_runtime(BInterface $object_b){ 

leer sobre sólidos principios de diseño orientado a objetos.

http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

+0

Sí, definitivamente lo leeré, gracias. Y examinaré especialmente la interconexión y el resumen porque parece bastante interesante. – SineCosine

Cuestiones relacionadas