Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Klasa w klasie?
Tarcil
post
Post #1





Grupa: Zarejestrowani
Postów: 41
Pomógł: 0
Dołączył: 24.11.2006

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


Witam serdecznie!

Od jakiegoś czasu próbuję opanować OOP w PHP i idzie mi, nie przymierzając, słabo. Mój problem polega na tym, że nie potrafię z jednej klasy odwołać się do metod innej. Nie wiem, czy to nie jest przypadkiem durnota jakaś i mój błąd w próbie myślenia obiektowo... proszę o pomoc w każdym bądź razie.

Mam klasę MySqlEng(). Konstruktor tej klasy tworzy połączenie z bazą danych i zapisuje uchwyt połączenia w prywatnej zmiennej klasy. Dalej mam 4 metody: selectQuery, updateQuery, insertQuery i deleteQuery, które przygotowują w prywatnej zmiennej $query string, który metodzie doQuery() służy do wykonania odpowiedniego zapytania w bazie danych. Dochodzi jeszcze metoda fetchResults(), która pozwala na przewijanie rekordów uzyskanych w odpowiedzi na zapytanie.

Standardowo używam tej klasy tak:
  1. <?php
  2. $sql = new MySqlEng();
  3.  
  4. $sql -> selectQuery('nazwa, ilosc', 'produkty', 'id > 93');
  5. while($res = $sql->fetchResults())
  6. {
  7. echo $res['nazwa'].' pozostała ilość: '.$res['ilosc'].'<br />';
  8. }
  9. ?>


Próbuję teraz złożyć klasę pagesSupport(), której zadaniem będzie: dodawanie stron do bazy danych, ich edycja i zmiana, oraz wyciągnie z bazy danych o odpowiedniej podstronie i wyswietlanie jej na ekranie. Zwykłe użycie wewnątrz metody tej klasy metody $sql->selectQuery() wywołuje błąd...

Jak skorzystać z klasy MySqlEng() wewnątrz klasy pagesSupport()(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)

Podaję też kod klasy MySqlEng():
  1. <?php
  2. //config
  3.    //this data should be inserted in another file, which is not available  by http://
  4.    define('DATABASE_HOST', 'localhost');
  5.    define('DATABASE_USER', 'tarcil_gsms');
  6.    define('DATABASE_PASS', 'gsms123');
  7.    define('DATABASE_NAME', 'tarcil_gsms');
  8.    
  9.    class MySqlEng
  10.        {
  11.        private $handler;
  12.        public $query;
  13.        private $results;
  14.        private $affected_rows;
  15.        private $last_row_id;
  16.        private $selected_rows;
  17.        public $records = array();
  18.        
  19.        
  20.        public function __construct()
  21.            {
  22.            if(@!$sql_handler = mysql_connect(DATABASE_HOST, DATABASE_USER, DATABASE_PASS))
  23.                {
  24.                throw new Exception('Problem z połączeniem do bazy danych.<br />Nr błędu: <b>'.mysql_errno().'</b><br /><b>Komunikat: </b>'.mysql_error());
  25.                }
  26.            else
  27.                {
  28.                if(!mysql_select_db(DATABASE_NAME))
  29.                    throw new Exception('Problem z wybraniem bazy danych.<br />Nr błędu: <b>'.mysql_errno().'</b><br /><b>Komunikat: </b>'.mysql_error());
  30.                else
  31.                    {
  32.                    //connection successfull:
  33.                    $this->handler = $sql_handler;
  34.                    unset($sql_handler);
  35.                    }
  36.                }
  37.            }
  38.            
  39.        //next four methods create sql query for doQuery method;
  40.        public function selectQuery($fields, $table, $where = "", $order = "", $limit = "")
  41.            {            
  42.            //if is another query saved:
  43.            if($this->query) unset($this->query);
  44.            
  45.            //creating query for doQuery() method
  46.            $this->query = 'SELECT '.$fields.' FROM '.$table;
  47.            if($where)
  48.                $this->query .= ' WHERE '.$where;
  49.            if($order)
  50.                $this->query .= ' ORDER BY '.$order;
  51.            if($limit)
  52.                $this->query .= ' LIMIT '.$limit;
  53.                
  54.            $this->doQuery();
  55.            $this->selected_rows = mysql_num_rows($this->results);
  56.            }
  57.            
  58.        TUTAJ SĄ JESZCZE TRZY METODY DO USTAWIANIA ZMIENNEJ QUERY... (updateQuery, deleteQuery, insertQuery)
  59.  
  60.            
  61.        //here is private method which will really make operations in db. it gets no arguments - all are written in object properties.
  62.        
  63.        private function doQuery()
  64.            {
  65.            if(!$this->results = mysql_query($this->query, $this->handler))
  66.                {
  67.                throw new Exception('Problem z wywołaniem zapytania do bazy danych.<br />Nr błędu: <b>'.mysql_errno().'</b><br /><b>Komunikat: </b>'.mysql_error());
  68.                }
  69.            }
  70.        
  71.        public function fetchResults()
  72.            {
  73.            if($this->results)
  74.                {
  75.                $this->records = mysql_fetch_array($this->results, MYSQL_ASSOC);
  76.                
  77.                if(is_array($this->records))
  78.                    {
  79.                    return $this->records;
  80.                    }
  81.                }
  82.            }
  83.            
  84.        public function getAffectedRows()
  85.            {
  86.            return $this->affected_rows;
  87.            }
  88.        public function getSelectedRows()
  89.            {
  90.            return $this->selected_rows;
  91.            }
  92.        public function getLastRowId()
  93.            {
  94.            return $this->last_row_id;
  95.            }
  96.        
  97.        public function __destruct()
  98.            {
  99.            mysql_close($this->handler);
  100.            }
  101.        }
  102. ?>
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 14)
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Albo przekazujesz obiekt klasy MysqlEng do obiektu klasy pagesSupport poprzez argument jakiejś metody/konstruktora:
  1. <?php
  2.  
  3. require_once 'mysqleng.class.php';
  4. require_once 'pagessupport.class.php';
  5.  
  6. $db = new MysqlEng();
  7. $ps = new pagesSupport('jakies', 'arg.', $db);
  8. ?>
A w konstruktorze bądź innej metodzie:
  1. <?php
  2. public function __construct($abc, $def, MysqlEng $db){
  3.  //...
  4.  $this->db = $db; //$this->db to jakies pole prywatne
  5. }
  6. ?>


Albo korzystając z Singletonu, Rejestru czy jeszcze czegos innego, byle nie globali.


EDIT:
I to o co pytasz to obiekt wewnątrz obiektu. PHP nie umożliwia zapiania klasy w klasie (nested classes).

Ten post edytował Crozin 28.12.2008, 13:08:43
Go to the top of the page
+Quote Post
plurr
post
Post #3





Grupa: Zarejestrowani
Postów: 175
Pomógł: 12
Dołączył: 28.06.2007
Skąd: Bytom

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


takie rzeczy to tylko w javie (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) A szkoda.
Go to the top of the page
+Quote Post
LBO
post
Post #4





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


To o czym pisze kolega Crozin to tak zwane inversion of control.
TDzieki temu możesz uczynić kod bardziej uniwersalnym.

  1. <?php
  2. /*
  3.  * Ogólny interfejs dla abstrakcji zapytań.
  4.  *
  5.  * Interfejs wymusza na klasie go implementującej posiadanie odpowiednich metod.
  6.  *
  7.  */
  8. interface DatabaseQueries
  9. {
  10.    public function __construct(array $config);
  11.  
  12.    public function selectQuery();
  13.  
  14.    public function updateQuery();
  15.  
  16.    public function deleteQuery();
  17.  
  18.    public function  insertQuery();
  19. }
  20.  
  21. // omijam z lenistwa argumenty dla metod :)
  22. class MySqlQueries implements DatabaseQueries
  23. {
  24.    public function __construct(array $config)
  25.    {
  26.        // implementujesz łączenie się z bazą na podstawie tablicy $config dla MySQL
  27.    }
  28.  
  29.    public function selectQuery()
  30.    {
  31.        // implementujesz zapytanie dla MySQL
  32.    }
  33.  
  34.    public function updateQuery()
  35.    {
  36.        // implementujesz zapytanie dla MySQL
  37.    }
  38.  
  39.    public function deleteQuery()
  40.    {
  41.        // implementujesz zapytanie dla MySQL
  42.    }
  43.  
  44.    public function  insertQuery()
  45.    {
  46.        // implementujesz zapytanie dla MySQL
  47.    }
  48. }
  49.  
  50. // omijam z lenistwa argumenty dla metod :)
  51. class SQLiteQueries implements DatabaseQueries
  52. {
  53.    public function __construct(array $config)
  54.    {
  55.        // implementujesz łączenie się z bazą na podstawie tablicy $config dla SQLite
  56.    }
  57.  
  58.    public function selectQuery()
  59.    {
  60.        // implementujesz zapytanie dla SQLite
  61.    }
  62.  
  63.    public function updateQuery()
  64.    {
  65.        // implementujesz zapytanie dla SQLite
  66.    }
  67.  
  68.    public function deleteQuery()
  69.    {
  70.        // implementujesz zapytanie dla SQLite
  71.    }
  72.  
  73.    public function  insertQuery()
  74.    {
  75.        // implementujesz zapytanie dla SQLite
  76.    }
  77. }
  78. ?>


a potem:

  1. <?php
  2. $config = array(
  3. 'host' => 'localhost',
  4. 'user' => 'username',
  5. // etc
  6. );
  7.  
  8. $db = new MysqlQueries($config);
  9. $ps = new pagesSupport();
  10. $ps->setDatabase($db);
  11. ?>


lub

  1. <?php
  2. $config = array(
  3. 'filename' => '/usr/data/database.sqlite3'
  4. );
  5.  
  6. $db = new SQLiteQueries($config);
  7. $ps = new pagesSupport();
  8. $ps->setDatabase($db);
  9. ?>


I dzięki temu możesz w pewnym ograniczonym stopniu zmieniać bazę bez ingerencji w kod.

Jak widzisz użyłem metody (tzw setter), żeby przekazać klasę odpowiedzialną za zapytania na bazie danych. Jest to wygodniejsze od parametru w konstruktorze.

Cytat(Crozin @ 28.12.2008, 13:06:41 ) *
Albo korzystając z Singletonu, Rejestru czy jeszcze czegos innego, byle nie globali.


A powiedz czym się różni w użytkowaniu taki Rejestr od globali, prócz ujęcia w OOP?
Go to the top of the page
+Quote Post
wlamywacz
post
Post #5





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Cytat
A powiedz czym się różni w użytkowaniu taki Rejestr od globali, prócz ujęcia w OOP?

Różni się tym że nie możesz go nadpisać, raz ustalony i tak zostaje do końca.
Go to the top of the page
+Quote Post
LBO
post
Post #6





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


Cytat(wlamywacz @ 1.01.2009, 20:23:56 ) *
Różni się tym że nie możesz go nadpisać, raz ustalony i tak zostaje do końca.


Nie rozumiem. Chodzi Tobie o to, że nie można nadpisać obiektów, które trzyma? Bo jak tak to muszę Ciebie zmartwić - powszechne implementacje nie biorą Tego pod uwagę (patrz Zend_Registry) i szczerze mówiąc takie podejście nie wynika jakoś jasno z założen tego wzorca.
Go to the top of the page
+Quote Post
wlamywacz
post
Post #7





Grupa: Zarejestrowani
Postów: 535
Pomógł: 27
Dołączył: 3.05.2005

Ostrzeżenie: (20%)
X----


Każdy dostosowuje wzorzec do swoich potrzeb, nie są one sztywno ustalone.
Go to the top of the page
+Quote Post
LBO
post
Post #8





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


Cytat(wlamywacz @ 1.01.2009, 23:24:24 ) *
Każdy dostosowuje wzorzec do swoich potrzeb, nie są one sztywno ustalone.


1. Tym bardziej nie możesz tego używać jako argumentu.
2. Taki sposób nie jest zbyt wygodny wbrew pozorom. Zakładam, że nie robisz testów jednostkowych.
3.
Cytat
[...] szczerze mówiąc takie podejście nie wynika jakoś jasno z założen tego wzorca.
Go to the top of the page
+Quote Post
pinochet
post
Post #9





Grupa: Zarejestrowani
Postów: 120
Pomógł: 12
Dołączył: 9.10.2008
Skąd: Tricity.Rumia()

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


Cytat(Tarcil @ 28.12.2008, 12:42:42 ) *
... nie potrafię z jednej klasy odwołać się do metod innej.

No niestety tak się czasem zdarza, że w schemacie klas są pomiędzy nimi strzałki :] I wtedy tak jak koledzy pokazali przekazujemy referencję do obiektu w konstruktorze lub innej meodzie importującej ( nie jest to oczywiście jedyne rozwiązanie ale jest najlepsze)

Co do rejestru ... chciałem tylko powiedzieć, że w zasadzie nie różni się od globali ale czy BD różni się od globali ? Nie - no właśnie dlatego tworzymy warstwę danych aby wszystko co z nimi związane było "gdzieś" a nie wszędzie :]

@plurr oprócz Javy na świecie jest jeszcze jeden język: C# (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) BTW PHP nie jest OO :[
Go to the top of the page
+Quote Post
wrzasq
post
Post #10





Grupa: Zarejestrowani
Postów: 206
Pomógł: 18
Dołączył: 6.03.2006
Skąd: Szczecin

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


@pinochet: jest wiele języków, a nested classes to nawet w C++ istnieją (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) . taki offtopic mały jak już chcemy uściślać (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif) .
Go to the top of the page
+Quote Post
phpion
post
Post #11





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(pinochet @ 3.01.2009, 06:56:25 ) *
BTW PHP nie jest OO :[

OO? Object Oriented? Jeśli tak to cię zmartwię: PHP, podobnie jak np. C++, jest językiem zorientowanym obiektowo, natomiast nie jest (jak np. Java) językiem obiektowym.
Go to the top of the page
+Quote Post
LBO
post
Post #12





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


Cytat(phpion @ 3.01.2009, 18:24:02 ) *
językiem zorientowanym obiektowo / językiem obiektowym.



To ja też Ciebie zmartwię - nie ma czegoś takiego jak język zorientowany obiektowo (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
phpion
post
Post #13





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(LBO @ 3.01.2009, 20:32:01 ) *
To ja też Ciebie zmartwię - nie ma czegoś takiego jak język zorientowany obiektowo (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

(IMG:http://forum.php.pl/style_emoticons/default/worriedsmiley.gif) jak to w takim razie jest? Mnie na uczelni uczono właśnie takiego rozgraniczenia.

// Edit:
Język zorientowany obiektowo - umożliwia pisanie kodu zarówno stukturalnie jak i obiektowo.
Język obiektowy - umożliwia pisanie kodu tylko obiektowo.
Tak mnie uczono...

Ten post edytował phpion 3.01.2009, 18:37:49
Go to the top of the page
+Quote Post
LBO
post
Post #14





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


OO to jest paradygmat... natomiast języki mogą mieć typy np. obiektowy język albo język z elementami tegoż (IMG:http://forum.php.pl/style_emoticons/default/tongue.gif)

edit:

Chcę tylko udowodnić, że nie warto się czepiać takich rzeczy - bo to normalne, że w naszym środowisku z czasem zaczynamy operować skrótami myślowymi.

Co złego to nie ja (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)

Alan

Ten post edytował LBO 3.01.2009, 18:42:58
Go to the top of the page
+Quote Post
Tarcil
post
Post #15





Grupa: Zarejestrowani
Postów: 41
Pomógł: 0
Dołączył: 24.11.2006

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


Wielki dzięki (IMG:http://forum.php.pl/style_emoticons/default/smile.gif) Przepraszam, że tu nie zaglądałem, ciężki okres ostatnio w pracy miałem. Serdecznie pozdrawiam (IMG:http://forum.php.pl/style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post

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: 17.09.2025 - 13:26