2012-04-06 10 views
5

Zasadniczo tworzę tylko dwie klasy, w których jedna klasa, w tym przypadku klasa A, uruchamia funkcję w innej klasie, w tym przypadku klasy B, w celu pobrania pewnych informacji z bazy danych.Konstruktor klasy ingerujący w inną klasę

Jednak, gdy B_runtime() faktycznie wywołuje bazę danych, pojawia się błąd Cannot access protected property A::$db.

Co ja nie rozumiem, jest to, że mimo, że mam dwie __construct JEST W obu klasach oświadczenie PDO są bardzo trwałe na temat korzystania z połączenia z bazą danych z klasy A.

Jestem pewien, że to ma coś do z tym, że używam B_runtime() z klasy A, ponieważ tak się nie stanie, jeśli zadzwonię do niego spoza klasy A.

Wiem, że mogę po prostu zmienić protected $db; w klasie A na publiczną zmienną jednak jestem bardzo ciekawa, jak mogę to naprawić.

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

Przepraszamy za długi kod - jeśli ktoś ma jakieś pomysły lub sugestie, byłby bardzo ceniony. Dzięki.

Odpowiedz

3

Można przekazać instancję B do metody. W ten sposób można również zdefiniować dependancy swojego sposobu na klasy 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();  
    } 
} 

Można nawet użyć type hinting w PHP 5, aby zasygnalizować, że spodziewasz instancję klasy B tam:

public function A_runtime(B $instance){ 
+0

Yea doskonałą odpowiedzią, jednak istnieje sposób, że mogę to zrobić z dwóch konstruktorów jak ja teraz robi? – SineCosine

+0

@SineCosine Możesz zachować wszystkich swoich konstruktorów. Właśnie umieściłem znak "// ...", na którym jest konstruktor, wszystko pozostaje takie samo. Zmienia się tylko metoda ("A_runtime") i sposób jej wywoływania. – kapa

+0

Och, zupełnie to przegapiłem. Dzięki, nie wiedziałem, że możesz to zrobić. – SineCosine

3

Oy .

Najpierw wywołuje się metodę niestatyczną jako metodę statyczną.

B::B_runtime(); 

powinny być stosowane tylko w ten sposób, jeśli B_runtime zostały zadeklarowane jako statyczne metody

static public function B_runtime(){ 

drugim klasa ma uzależnienia zewnętrznego, który jest powszechnie uważany nie jest dobra. klasa powinna polegać tylko na tym, co jest jej dane, a nie na globaliach. nazywane jest to zasadą inwersji zależności. jeśli klasa jest zależna od czegoś, powinieneś podać tę zależność za pomocą argumentu, a nawet lepiej, użyj podpowiedzi typu, aby upewnić się, że zależność ma metody, których się spodziewasz.

public function A_runtime(B $object_b){ 

Aby to zrobić krok dalej, należy również używając streszczeń lub interfejsy typu podpowiedzi zamiast konkretnych klas. w ten sposób możesz przełączyć B na inną wersję B, jeśli okaże się to konieczne.

interface BInterface { 
    public function B_runtime(); 
} 

następnie

public function A_runtime(BInterface $object_b){ 

przeczytać na solidnych zasad projektowania OO.

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

+0

Tak, zdecydowanie to przeczytam, dzięki. Szczególnie zajrzę do interfejsu i abstrakcji, ponieważ wygląda całkiem interesująco. – SineCosine

Powiązane problemy