Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP]Wywoływanie klasy w klasie
sannin
post
Post #1





Grupa: Zarejestrowani
Postów: 308
Pomógł: 13
Dołączył: 31.10.2008

Ostrzeżenie: (0%)
-----


Witam,

dopiero zaczynam swoją zabawę z obiektowym php. Teraz mam pytanie do bardziej zaawansowanych koderów czy moje rozwiązanie jest dobre. Więc tak mam folder gdzie tworzę pliki z klasami dajmy 'Mysql.class.php'. W pliku library.php ładuje wszystkie klasy

  1. <?php
  2. require('Mysql.class.php');
  3.     require('Main.class.php');
  4. ?>


w pliku system.php ładuje library.php i config.php Natomiast w pliku index.php mam

  1. <?php
  2. require('config/system.php');
  3.    
  4.     $mysql = new MySql;
  5.     $mysql->Connect($CONFIG['dbHost'], $CONFIG['dbUser'], $CONFIG['dbPassword'], $CONFIG['dbName']);
  6.    
  7. ...
  8.  
  9.     $index = new Main();
  10.     $index->prace());
  11. ?>


Teraz żeby uzyskać dostęp do mysql w klasie Main, metodzie prace mam coś takiego

  1. <?php
  2. function prace()  {    
  3.             global $mysql;
  4.            
  5.             $job = $mysql->selectToArray("tabela", "id, name", "id > 3", "");
  6.             foreach($job['name'] as $value) {
  7.                 echo $value.'
  8.     ';
  9.             }
  10.         }
  11. ?>


Czy ogólnie jest to poprawne podejście? Czy raczej wystrzegać się global? Jak to inaczej rozwiązać? Proszę mi nie proponować Zend'a itd. bo najpier chciałbym liznąć troszkę obiektówki (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Pozdrawiam i z góry dziękuje za pomoc.
Powód edycji: Proszę używać tagu [PHP] do umieszczania kodu PHP. Dodane także tagi do tematu.
Go to the top of the page
+Quote Post
2 Stron V   1 2 >  
Start new topic
Odpowiedzi (1 - 19)
erix
post
Post #2





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Czy ogólnie jest to poprawne podejście? Czy raczej wystrzegać się global?

Się wystrzegać. Do tego zadania doskonale sprawdzi się singleton.
Go to the top of the page
+Quote Post
l0ud
post
Post #3





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

Ostrzeżenie: (0%)
-----


Cytat
Się wystrzegać. Do tego zadania doskonale sprawdzi się singleton.

...który tylko 'ładniej' wygląda. (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)

Utwórz klasę łączącą wszystkie (zawierającą w sobie tablicę wszystkich obiektów) i przekazuj jej instancję do wszystkich nowo utworzonych obiektów. Musi zawierać metody, dzięki którym pozwoli na dostęp do obiektów z zewnątrz, oraz najlepiej od razu je wczytywać.

Jakiś uproszczony przykład:

index.php
  1. <?php
  2. include ('includes/core.php');
  3.  
  4. $core = new core;
  5.  
  6. $core->initComponents(); //tutaj można dodać obsługę ew. wyjątków
  7. ?>


core.php

core.php
  1. <?php
  2. class core {
  3.   private $obj = array();
  4.  
  5.   public function __get($objName) {
  6.      if (isset($this->obj[$objName])) return $this->obj[$objName];
  7.   }
  8.  
  9.   public function load($className) {
  10.      include('includes/'.$className.'.php');
  11.      $this->obj[$className] = new $obj($this);
  12.   }
  13.  
  14.  public function initComponents() {
  15.     $this->load('mysql');
  16.      $this->load('config'); //itd
  17.  }
  18.  
  19. }
  20. ?>


przykładowe config.php
  1. <?php
  2. class config {
  3.   private $db;
  4.   //inne obiekty, których tutaj potrzebujemy
  5.   public function __construct(core $core) {
  6.      //wczytywanie tych obiektów do klasy
  7.      $this->db = $core->db;
  8.      //itd.
  9.   }
  10.   public function action() { //i jakaś tam akcja tej klasy
  11.      $this->db->query('zapytanie');
  12.   }
  13. }
  14. ?>


Później jeszcze możesz dodać metodę startAction() do core, które wczyta właściwy plik, który będzie coś robił (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) Plik zostanie wczytany wewnątrz klasy core, a więc do obiektów będziesz się odnosił tam przez $this.
Go to the top of the page
+Quote Post
erix
post
Post #4





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Uzasadnij, w jaki sposób Twoje rozwiązanie jest lepsze od singletona?
Go to the top of the page
+Quote Post
sannin
post
Post #5





Grupa: Zarejestrowani
Postów: 308
Pomógł: 13
Dołączył: 31.10.2008

Ostrzeżenie: (0%)
-----


Już mniej lub więcej rozumiem o co chodzi ;p Teraz mam pytanie czy stosować new czy coś takiego
Kod
public function singleton()
    {
       static $instance;
       if(!isset($instance)) {
          $instance = new test5;
       }
       return $instance;
    }
i później
Kod
$single1 = test5::singleton();
Go to the top of the page
+Quote Post
Mize
post
Post #6





Grupa: Zarejestrowani
Postów: 84
Pomógł: 6
Dołączył: 26.03.2008
Skąd: Łódź

Ostrzeżenie: (0%)
-----


Takie, że przykładowo w Widoku nie masz dostępu do wszystkich komponentów.
Go to the top of the page
+Quote Post
erix
post
Post #7





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Jakoś nigdy nie miałem tego typu problemów z singletonem.
Go to the top of the page
+Quote Post
l0ud
post
Post #8





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

Ostrzeżenie: (0%)
-----


Cytat
Uzasadnij, w jaki sposób Twoje rozwiązanie jest lepsze od singletona?


Tak jak chociażby Mize powiedział, nie mogę np. w widoku wykonywać zapytań do bazy danych (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) Oczywiście o ile odpowiednio go obsłużę. No i wszystko mam w jednym miejscu, co daje pewien porządek.
Równie dobrze mógłbym spytać Ciebie, w czym, poza niemożnością nadpisania lepszy jest ten singleton od globala? (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
sannin
post
Post #9





Grupa: Zarejestrowani
Postów: 308
Pomógł: 13
Dołączył: 31.10.2008

Ostrzeżenie: (0%)
-----


Trochę poczytałem, nie wiem czy zrozumiałem ;d ale zrobiłem tak:

do każdej klasy dodałem na początku

Kod
private static $objInstance = null;
     private $intValue = null;
     ########################################################
     private function __construct() {
         $this->intValue = rand(1, 100);
     }
     ########################################################
     public static function create() {
         if (is_null(self::$objInstance)) {
             self::$objInstance = new self();
         }
         return self::$objInstance;
     }
     ########################################################


Później wywołuje to tak
Kod
$Mysql = MySql::Create();
$Mysql->Connect($CONFIG['dbHost'], $CONFIG['dbUser'], $CONFIG['dbPassword'], $CONFIG['dbName']);
$Mysql->metoda();


W klasach muszę natomiast robić tak

Kod
MySql::selectToArray()
Czy może mi to kotś wytłumaczyć (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) ?
Go to the top of the page
+Quote Post
erix
post
Post #10





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Tak jak chociażby Mize powiedział, nie mogę np. w widoku wykonywać zapytań do bazy danych

Yyyyy... W widoku zapytania do bazy...? My mamy nadal na myśli MVC, czy mam w czymś braki?

Cytat
No i wszystko mam w jednym miejscu, co daje pewien porządek.

No z tym się zgodzę.

Cytat
poza niemożnością nadpisania lepszy jest ten singleton od globala?

Właśnie ta niemożność nadpisania. (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) Poza tym, łatwiej jest znaleźć deklarację obiektu, do którego się singleton odnosi. A w przypadku global szukaj wiatru w polu.

Osobiście korzystam z pewnego rodzaju "hybrydy"; wyznaję zasadę, że co jest wygodniejsze+wydajniejsze w użyciu. (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Go to the top of the page
+Quote Post
sannin
post
Post #11





Grupa: Zarejestrowani
Postów: 308
Pomógł: 13
Dołączył: 31.10.2008

Ostrzeżenie: (0%)
-----


Czy jest ktoś w stanie mi pomóc zamiast się wykłócać?
Go to the top of the page
+Quote Post
erix
post
Post #12





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
W klasach muszę natomiast robić tak

A zwykła konstrukcja create nie działa...? Nie wiem, jaką masz deklarację selectToArray...

PS. Poprosiłem już o wydzielenie wątku, jak coś.
Go to the top of the page
+Quote Post
sannin
post
Post #13





Grupa: Zarejestrowani
Postów: 308
Pomógł: 13
Dołączył: 31.10.2008

Ostrzeżenie: (0%)
-----


Działa, tylko że wtedy muszę od nowa łączyć się z mysql. Chciałbym, zeby coś takiego w pliku system.php

Kod
require('library.php');
require('config.php');
$mysql = MySql::Create();
$mysql->connect($CONFIG['dbHost'], $CONFIG['dbUser'], $CONFIG['dbPassword'], $CONFIG['dbName']);


Załatwiało sprawę połączenia. Później daje tylko $index->prace() w której mam selectToArray

Później mam wykonywać metody MySql::metoda czy $mysql->metoda ?

Ten post edytował sannin 20.11.2008, 22:59:38
Go to the top of the page
+Quote Post
erix
post
Post #14





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Później $mysql->metoda. Z dwukropkiem wywołujesz tylko metody oznaczone frazą static" title="Zobacz w manualu PHP" target="_manual w deklaracji.

Troszkę mało informacji podałeś, np. jak wywołujesz selectToArray.
Go to the top of the page
+Quote Post
sannin
post
Post #15





Grupa: Zarejestrowani
Postów: 308
Pomógł: 13
Dołączył: 31.10.2008

Ostrzeżenie: (0%)
-----


Poczytałem i wydaje mi się, że już to łapie... Dosyć pomocy był ten wpis http://athlan.pl/singleton-registry-map/ tylko autor pisze tutaj, że singleton nie jest najlepszym rozwiązaniem, ale przeszukują fora widzę, że jest to kwestia bardzo sporna które rozwiązanie jest najlepsze... Robię tak... do każdej klasy dodaje

Kod
private function __construct() {
         }
         ########################################################
         public static function instance() {
             if(!self::$_oInstance instanceof self) {
                 self::$_oInstance = new self;
             }        
             return self::$_oInstance;
         }
Później wystarczy tylko
Kod
$mysql = MySql::instance();
             $zmienna = $mysql->metoda()
Z tego co rozumiem to MySql::instance(); Utworzy obiekt, a jeśli istnieje to go zwróci, dzięki temu mogę działać tą klasą po całym "systemie" bez obaw i nie muszę się martwić nadpisaniem i mam pewność, że zawsze korzystam z tego samego wywołania obiektu. Czy dobrze to rozumiem i czy jest to dobre (nienajlepsze) rozwiązanie na używanie obiektowego php? Odchodząc od tematu mam jeszcze pytanie co do config.php w którym są przetrzymywane zmienne systemowe. Czy wstawiać tam stałe, żeby były dostępne wszędzie czy zmienne i wczytywać w funkcji jak globalne? Czy może jeszcze jakoś inaczej?
Go to the top of the page
+Quote Post
erix
post
Post #16





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
tylko autor pisze tutaj, że singleton nie jest najlepszym rozwiązaniem, ale przeszukują fora widzę, że jest to kwestia bardzo sporna

Między innymi dlatego wynikł offtop w tym temacie. ;P

Cytat
Z tego co rozumiem to MySql::instance(); Utworzy obiekt, a jeśli istnieje to go zwróci, dzięki temu mogę działać tą klasą po całym "systemie" bez obaw i nie muszę się martwić nadpisaniem i mam pewność, że zawsze korzystam z tego samego wywołania obiektu.

Czyli dobrze zrozumiałeś. (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Cytat
Czy wstawiać tam stałe, żeby były dostępne wszędzie czy zmienne i wczytywać w funkcji jak globalne? Czy może jeszcze jakoś inaczej?

Hmm, to kwestia tak samo sporna, jak wyżej. Choć powstały pewne niepisane zasady, jak np. trzymanie ścieżek do katalogów aplikacji w stałych, itp. Przejrzyj sobie źródła paru skryptów (mam na myśli skryptów, a nie jakichś beznadziejnych "systemów" newsowych pisanych przez samozwańczych "programistów"), to sam wyciągniesz wnioski.
Go to the top of the page
+Quote Post
l0ud
post
Post #17





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

Ostrzeżenie: (0%)
-----


Cytat
Odchodząc od tematu mam jeszcze pytanie co do config.php w którym są przetrzymywane zmienne systemowe. Czy wstawiać tam stałe, żeby były dostępne wszędzie czy zmienne i wczytywać w funkcji jak globalne? Czy może jeszcze jakoś inaczej?


Jeżeli chodzi o mnie, to w takim pliku definiuję kilka stałych, które są niezbędne do zainicjowania właściwego obiektu, który zajmuje się konfiguracją i wczytuje wartości z bazy oraz które wystarczą do w miarę eleganckiego obsłużenia błędu, jeżeli coś się posypie. Z reguły są to dane do bazy oraz ścieżki do poszczególnych folderów. Czasem umieszczę jakąś wartość, której nie planuję zmieniać przez panel administracyjny, a która może się przydać przy późniejszej przebudowie skryptu. Takie rzeczy jednak, jak np. ilość elementów na stronie (do paginacji) trzymam już w bazie, z możliwością zmiany w PA (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
sannin
post
Post #18





Grupa: Zarejestrowani
Postów: 308
Pomógł: 13
Dołączył: 31.10.2008

Ostrzeżenie: (0%)
-----


Cytat(l0ud @ 21.11.2008, 22:40:45 ) *
Takie rzeczy jednak, jak np. ilość elementów na stronie (do paginacji) trzymam już w bazie, z możliwością zmiany w PA (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)


Tak robię, bardziej chodziło mi o adres email admina itd. W sumie mam taki pomysł na to, w pliku config.php trzymam tylko dane do połączenie z mysql. Tworzę sobie klasę o nazwie Config która będzie pobierała z mysql wszystkie inne wartości. Dzięki temu będę miał do nich dostęp wszędzie i możliwość edycji z PA. Czy jest to dobre rozwiązanie (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) ?

Ten post edytował sannin 21.11.2008, 23:57:18
Go to the top of the page
+Quote Post
erix
post
Post #19





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




To już jak Tobie wygodniej. (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)

Choć dobrym sposobem jest inicjowanie połączenia bezpośrednio z pliku konfiguracyjnego, gdyż dane do SQL nie są przechowywane w zmiennych i nie można ich już tak łatwo odczytać.
Go to the top of the page
+Quote Post
adek140
post
Post #20





Grupa: Zarejestrowani
Postów: 2
Pomógł: 0
Dołączył: 31.07.2009

Ostrzeżenie: (0%)
-----


Cytat(l0ud @ 20.11.2008, 20:59:13 ) *
core.php
  1. <?php
  2. class core {
  3.   private $obj = array();
  4.  
  5.   public function __get($objName) {
  6.      if (isset($this->obj[$objName])) return $this->obj[$objName];
  7.   }
  8.  
  9.   public function load($className) {
  10.      include('includes/'.$className.'.php');
  11.      $this->obj[$className] = new $obj($this);
  12.   }
  13.  
  14.  public function initComponents() {
  15.     $this->load('mysql');
  16.      $this->load('config'); //itd
  17.  }
  18.  
  19. }
  20. ?>


12 linijka w pliku powyżej powoduje błąd (IMG:http://forum.php.pl/style_emoticons/default/sad.gif)
Fatal error: Class name must be a valid object or a string in H:\Serwer\tescik\includes\core.php on line 11

jakaś wskazówka?
tutaj pliczki http://wyslijto.pl/plik/u0rcn5sg8s
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.08.2025 - 04:14