2012-10-09 8 views
7

Pracuję nad przejściem do OOP w PHP. Mam objaśnienia do czytania na php.net, ale miałem nadzieję, że mogę tu uzyskać pewne konkretne odpowiedzi.Jak konstruować klasy w PHP

Próbowałem utworzyć następujący przykład ilustrujący moje pytanie. Załóżmy, że mam klasy "Baza danych", "Produkty" i "Użytkownicy" i chcę wyświetlać produkty, jeśli użytkownik ma do nich dostęp.

Dlatego nazywam klasę "Produkty" funkcją "showProducts()", która z kolei tworzy instancję klasy "Użytkownik", która tworzy instancję obiektu "Baza danych" i sprawdza poziom dostępu użytkowników.

Jeśli użytkownik ma dostęp, funkcja "showProducts()" tworzy kolejną instancję obiektu "Baza danych" i wysyła zapytanie do bazy danych.

class Database{ 

    public function query(){ 
     //runs query here 
    } 

    public function __construct() { 
     //sets up connection here 
    } 

} 

class User{ 

    public function checkAccess(){ 
     $db = new Database(); 
     $db->query(//pass in query to check access) 
     //does stuff, then returns true or false 
    } 

} 

class Products{ 

    public function showProducts(){ 

     $user = new User(); 

     if($user->checkAccess()) 
     $db = new Database(); 
     $db->query(//pass in query to get products) 
     } 

} 

Miałem nadzieję, że ktoś może zilustrować, jak to zrobić w odpowiedni sposób.

Chciałbym mieć jakąś klasę kontrolera, która tworzy jeden obiekt "Bazy danych", który jest dostępny dla wszystkich klas, które muszą uzyskać do niego dostęp, bez konieczności tworzenia wielu wystąpień obiektu "Baza danych". Chciałbym to samo z klasą użytkowników, więc istnieje jeden obiekt $ users, do którego wszystkie klasy mogą uzyskać dostęp, bez konieczności tworzenia nowego obiektu za każdym razem, gdy potrzebuję użyć czegoś w klasie "Użytkownik".

Przepraszam, jeśli moje pytanie nie jest jasne, iz góry dziękuję za wszelkie odpowiedzi !!

Dziękuję wszystkim za odpowiedzi!

Odpowiedz

11

Przy przechodzeniu z procedury proceduralnej na programowanie zorientowane obiektowo powinieneś pojąć więcej niż tylko jak budować klasy. OOP nie pisze zajęć, chodzi o przestrzeganie najlepszych praktyk, zasad i wzorców w OOP.

Nie powinieneś tworzyć instancji nowych obiektów w innym, powinieneś podać obiekt użytkownika, jego obiekt bazy danych, od którego zależy użytkownik, za pomocą konstruktora lub metody ustawiającej. Nazywa się to Dependency Injection. Celem jest nadanie obiektom klasy, która ich potrzebuje, za pomocą metody konstruktora lub ustawiacza. I powinny być instancjonowane spoza tej klasy, więc łatwiej jest skonfigurować klasę. A kiedy budujesz klasę, chcesz łatwo zobaczyć, jakie zależności posiada ta klasa. Można przeczytać o Inversion zasady sterowania tutaj: IoC

Więc Twój kod będzie wyglądać następująco:

<?php 

// User object that depends on Database object, and expects it in constructor. 

class User 
{ 
    protected $database; 

    public function __construct($database) 
    { 
     $this->database = $database; 
    } 

    // -- SNIP -- 
} 

?> 

teraz wykorzystać tę klasę użytkownika to zrobić:

<?php 

    $database = new Database($connParams); 
    $user = new User($database); 

?> 

Można używaj również Dependency Injection, używając metod ustawiających, aby ustawić zależności, ale pozwolę ci to samemu na to :) :)

To prawda, potocz się przeczytaj o Inversion of Contro Tak więc, to są najlepsze sposoby na zarządzanie klasami, a także na temat Injection Injection Containers Injection Containers.

Widziałem wiele kodu PHP, który jest "OOP" i w rzeczywistości używają one tylko klas jako przestrzeni nazw funkcjonalności :) Tak więc potocz się nauczyć o zasadach i wzorach OOP.

Miłej zabawy! :)

+0

Wielkie dzięki za odpowiedź!Więc gdybym miał inną klasę, która odwoływałaby się do klasy użytkownika, również przekazałbym obiekt $ user jako parametr? – Ben

+0

Tak, możesz! Możesz przekazać tyle klas, ile chcesz. Możesz przekazać obiekt przez konstruktor, jeśli obiekt naprawdę potrzebuje tego obiektu do działania. I możesz przekazać to za pomocą metody ustawiającej, jeśli obiekt jest opcjonalny. Gdy otrzymasz skomplikowane zależności, możesz pomyśleć o użyciu Dependency Injection Container, w którym opisujesz zależności, a Container będzie w stanie zebrać obiekt z innych obiektów i zwróci go Tobie :) Więcej na temat Dependency Injection and Dependency Injection Container możesz przeczytać tutaj : http://fabien.potencier.org/article/12/do-you-need-a-dependency-injection-container – otporan

0

Aby jeden obiekt dla wszystkich użycie kodu Singleton wzoru:

class Database{ 
    private $db_descriptor; 

    private function __construct(){ 
     /* connect and other stuff */ 
    } 
    public static function getInstance(){ 
     static $instance; 
     if($instance === null){ 
      $instance = new self(); 
     } 
     return $instance; 
    } 
} 

i można użyć tej samej techniki z użytkownikami, mówię więcej z PHP 5.4 można użyć 1 cechę dla Singleton. Ostatnia wskazówka: podczas pracy z bazą danych i innymi ciężkimi przedmiotami należy zastosować technikę o nazwie lazy initialization. Kiedy poprawisz swoje umiejętności OOP, spójrz na Doctrine Project, które często używają tych technik!

+0

Właściwie polecam teraz przeglądanie przykładów z frameworków dla przedsiębiorstw, aby poznać sposób ich wykonywania. Możesz nie potrzebować tego od razu, ale dadzą ci dobry pomysł na strukturę. – prodigitalson

+0

Czy możesz doradzić? Nie pracowałem z nimi wcześniej. – kirugan

+1

Symfony2 i Zend2 Frameworks to jedyne frameworki warte obejrzenia :) Wiem, że dostanę za to dużo głosów na dół. Ale ci dwoje są najlepsi, aby nauczyć się prawidłowego OOP w PHP! – Limeni

2

Nie tworzyj instancji obiektów wewnątrz konstruktorów ani innych metod. Przekaż je jako parametr, najlepiej w innej klasie znanej jako fabryka. Ułatwi to testowanie kodu, ale także ułatwi tworzenie obiektów.

Nie należy również używać pojedynczych znaków. Jest to zorientowana obiektowo wersja "zmiennych globalnych" i nie chcesz używać zmiennych globalnych. To sprawia, że ​​testowanie twojego kodu jest naprawdę trudne, prawie niemożliwe.

Obejrzyj ten film wideo http://www.youtube.com/watch?v=-FRm3VPhseI, aby zrozumieć, dlaczego korzystanie z singletonów jest złe. Szczególnie wart obejrzenia przykład CreditCard o godzinie 19:00.

Jeśli naprawdę chcesz to zrobić w najnowocześniejszej formie, przyjrzyj się koncepcji "wstrzyknięcia zależności". Zasadniczo, przekazywanie rzeczy, które są potrzebne z zewnątrz, do klasy, jest tajemnicą, ale istnieją ramy, które robią to automatycznie, więc nie musisz już sam pisać fabryk. Są one nazywane "Dependency Injection Container" lub "DIC".

+0

Wielkie dzięki! Googleing klasa fabryk teraz. Czy znasz jakieś dobre ogólne samouczki dotyczące konfigurowania struktur klas dla witryn internetowych? Zaczynam rozumieć zasady, ale jeśli chodzi o praktyczne wdrożenie, jestem trochę zagubiony. – Ben

+0

Najpierw polecam przyjrzeć się autoloadingowi. Istnieje kilka systemów, które ułatwiają to zadanie, ale sprowadza się to do organizowania twoich klas - jedna klasa na plik - w drzewie katalogów i odpowiedniego dopasowywania nazw klas tak, aby autoloader, który pobiera tylko potrzebną nazwę klasy jako parametr, może konstruować ścieżka i nazwa pliku, w którym powinna się znajdować klasa. Spójrz na Zend Framework (1 lub 2), aby zobaczyć przykład. Możesz się zorientować, jak inni też nazywają swoje zajęcia. – Sven