2012-04-06 9 views
5

По существу, я просто создаю два класса, в которых один класс, в этом случае класс A, запускает функцию в другом классе, в данном случае классе B, для захвата некоторой информации из базы данных.Класс конструктора, связанный с другим классом

Однако, когда B_runtime() действительно звонит в базу данных, я получаю сообщение об ошибке Cannot access protected property A::$db.

То, что я не понимаю, что даже если у меня есть два __construct «с в обоих классах заявление ПДО настойчивыми об использовании подключения к базе данных из класса А.

Я уверен, что это что-то сделайте это с тем, что я запускаю B_runtime() из класса А, потому что этого не происходит, если я вызываю его из-за пределов класса A.

Я знаю, что я могу просто изменить protected $db; в классе A на общедоступную переменную , однако, мне действительно интересно, как я могу это исправить.

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']; 
    } 
} 

Извините за длинный код - если у кого есть идеи или предложения, будем рады. Благодарю.

ответ

3

Вы можете передать экземпляр 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();  
    } 
} 

Вы можете даже использовать type hinting в PHP 5, чтобы показать, что вы ожидаете экземпляр класса B: там

public function A_runtime(B $instance){ 
+0

Да идеальный ответ, однако, есть способ, что я могу сделать это с двумя конструкторами, как я делаю сейчас? – SineCosine

+0

@SineCosine Вы можете сохранить все свои конструкторы. Я просто поместил метку '// ...', где находится конструктор, все остается неизменным. Только метод ('A_runtime') и способ его изменения. – kapa

+0

О, полностью пропустил это. Спасибо, я не знал, что ты это можешь. – SineCosine

3

Oy ,

Во-первых, вы вызываете нестатический метод как статический метод.

B::B_runtime(); 

следует использовать только в этом случае, если B_runtime были объявлены как статический метод

static public function B_runtime(){ 

второй, ваш класс имеет внешнюю зависимость, которая, как правило, считается не очень хорошо. класс должен полагаться только на то, что ему дано, а не на глобальные. это называется принципом инверсии зависимостей. если класс зависит от somthing, вам придется придать ему эту зависимость через аргумент, и даже лучше использовать подсказку типа, чтобы убедиться, что зависимость имеет методы, которые вы ожидаете.

public function A_runtime(B $object_b){ 

Для того, чтобы это шаг дальше, вы также должны использовать тезисы или интерфейсы для типа намекая вместо конкретных классов. таким образом вы можете переключить B с другой версией B, если это когда-либо понадобится.

interface BInterface { 
    public function B_runtime(); 
} 

затем

public function A_runtime(BInterface $object_b){ 

читать на SOLID принципы проектирования ОО.

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

+0

Да, я обязательно прочитаю это, спасибо. И я буду особенно смотреть на сопряжение и абстрагирование, потому что это выглядит довольно интересно. – SineCosine

Смежные вопросы