Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Połączenie z bazą danych, raz., Wygodne i bez zbędnego pisania
fannet
post
Post #1





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 28.11.2005

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


Witajcie piszę ponieważ mam od dłuższego czasu problem związany z programowaniem obiektowym, otóż staram się uczyć, ale nie jakoś chce do tej głowy wpadać, no ale do rzeczy otóż staram się pisać jakieś klasy w nich metody, ale większość z nich wymaga połączenia z bazą danych i wychodzi że na 10 klas w każdej mam w konstruktorze coś takiego:
  1. <?php
  2. function __construct()
  3. {
  4.  if(!$this->connect = new mysqli(HOST, USER, PASS, NAME))
  5.  {
  6.    throw new Exception("jak zwykle złe połączenie");
  7.  }
  8. }
  9. ?>
W programowaniu obiektowych chyba podstawowym założeniem jest aby kod się nie powtarzał i żeby jeden napisany kod był wykorzystywany wiele razy, a w moim przypadku wygląda to zupełnie odwrotnie.. Proszę o jakieś naprowadzenie mnie na tą właściwą drogę w mojej i tak już pomieszanej nauce.
Go to the top of the page
+Quote Post
_olo_1984
post
Post #2





Grupa: Zarejestrowani
Postów: 289
Pomógł: 77
Dołączył: 5.08.2006

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


napisz sobie prosty sterownik (klase) do mysql, potem używaj jej dowoli. Raz napisany kod wykorzystasz w każdym miejscu aplikacji. Przykładów jest bardzo dużo, poszukaj tu na formu lub google.Pozdr


--------------------
awake
Go to the top of the page
+Quote Post
fannet
post
Post #3





Grupa: Zarejestrowani
Postów: 9
Pomógł: 0
Dołączył: 28.11.2005

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


Słowo kluczowe "sterownik" otworzyło mi bramę do wielu nowych lektur do analizy smile.gif
Załóżmy że już mam taki sterownik i teraz mi wychodzi na to że będę musiał w konstruktorze tworzyć nowy egzemplarz klasy?

Edit: Teraz pomyślałem przecież mogę chyba skorzystać z rozszerzenia wbudowanego w php mysqli? Wiec pozostaje pytanie jak się do tego odwołać.

Ten post edytował fannet 31.01.2009, 12:22:30
Go to the top of the page
+Quote Post
Pax95
post
Post #4





Grupa: Zarejestrowani
Postów: 50
Pomógł: 7
Dołączył: 31.01.2009

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


Nie widzę niczego złego w twojej klasie. Dodaj destruktor i wykorzystaj wzorzec Singleton, a obiekt inicjuj na początku dokumentu i się nie przejmuj połączeniem w innych klasach.


--------------------
Nie zapomnij o
Go to the top of the page
+Quote Post
skowron-line
post
Post #5





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

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


tak jak juz kolega wyżej napisał napisz sobie sterownik bazy danych a potem.
  1. <?php
  2. class user{
  3. public function __construct()
  4. {
  5. include_once( 'sterownik.sql.class.php' );
  6. $this->mysq = new sterownikMysql( 'host','user','pass','db' );
  7. }
  8. }
  9. ?>

dołącz go do każdej z klas.

Ten post edytował skowron-line 31.01.2009, 13:36:08


--------------------
I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy.

QueryBuilder, Mootools.net, bbcradio1::MistaJam
http://www.phpbench.com/
Go to the top of the page
+Quote Post
Pax95
post
Post #6





Grupa: Zarejestrowani
Postów: 50
Pomógł: 7
Dołączył: 31.01.2009

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


@UP: Właśnie nie o to mi chodziło :]. Połączenie tworzymy tylko jedno, nie inicjujemy go w każdej klasie.
EDIT: Nie będę żałował.
  1. <?php
  2. class Datebase
  3. {
  4.   private static $s_instance;
  5.  
  6.   private function __construct()
  7.   {
  8.      // Połączenie z bazą danych
  9.   }
  10.  
  11.   public static function getInstance()
  12.   {
  13.      if ( self::$s_instance === null )
  14.      {
  15.         self::$s_instance = new self;
  16.      }
  17.      return self::$s_instance
  18.   }
  19.  
  20.   public function __destruct()
  21.   {
  22.      // Usunięcie połączenia
  23.   }
  24. }
  25. ?>


Inicjujemy na samym początku np. index.php
  1. <?php
  2. $Datebase = Datebase::getInstance();
  3. //dalsze operacje
  4. ?>


Ten post edytował Pax95 31.01.2009, 13:59:28


--------------------
Nie zapomnij o
Go to the top of the page
+Quote Post
Tarcil
post
Post #7





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

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


Witam

Chciałbym dorzucić mój problem do tego tematu.

Napisałem klasę, która w konstruktorze tworzy połączenie z bazą danych oraz zawiera metody insertQuery, selectQuery itd, które przygotowują zapytanie do bazy, wykonywane prywatną metodą doQuery. Wszystko chodziło pięknie, ale był problem, kiedy przyszło zagnieździć zapytanie do bazy w zapytaniu. Już tłumaczę:

Załóżmy, że mamy dwie tabele.
  1. <?php
  2. Tabela news:
  3. ID int
  4. title varchar(255)
  5. time int
  6. text text
  7. authorID
  8. ?>

  1. <?php
  2. Tabela administrators:
  3. ID int
  4. name varchar(40)
  5. pass char(32)
  6. ?>


Tworzę sobie egzemplarz obiektu do obsługi bazy
  1. <?php
  2. $sql = new mySql(HOST, USER, PASS, NAME)
  3. ?>


Wyszukuję newsy w bazie:
  1. <?php
  2. $sql->selectQuery('title, time, authorID', 'news');
  3. while($news = $sql->fetchResults())
  4. {
  5. //wyświetlam news
  6. //tutaj musze wykonać coś takiego:
  7. mysql_query('SELECT name FROM administrators WHERE id='.$news['authorID']);
  8.  
  9. }
  10. ?>


Tyle, że nie po to pisałem klasę, żeby używać mysql_query(). To jedna sprawa, druga jest taka, że jeśli zamiast mysql_query() użyję znów $sql->selectQuery to zmieni mi to zapytanie używane do przewijania wyników w linijce while($news=$sql->fetchResults(). Muszę więc tworzyć dodatkowy obiekt (a to jest drugie połączenie z bazą danych - coś, czego trzeba unikać).
Sprawę rozwiązałem tak, że wydzieliłem kod połączenia z bazą danych do klasy mySqlConnect, a zapytania do klasy mySqlQueries. Tworzę jedno połączenie z bazą, a potem odpowiednio do potrzeb tworzę obiekty odpowiadające za przygotowanie zapytań do bazy:
  1. <?php
  2. $sql = new mySqlConnect(HOST, USER, PASS, DBNAME);
  3. $query_news = new mySqlQueries($sql->handler);
  4. $query_author = new mySqlQueries($sql->handler);
  5. $query_news->selectQuery('id, title, text, authorID', 'news');
  6. while($news = $query_news->fetchResults())
  7. {
  8. //wyświetlanie newsa...
  9. $query_author->selectQuery('name', 'administrators', 'id='.$news['authorID']);
  10. $admin = $query_author->fetchResults();
  11. //wyświetlenie nazwy autora newsa
  12. }
  13. $query_news->__destruct();
  14. $query_author->__destruct();
  15. ?>


Tak to działa u mnie... tylko, że coś mi mówi, że to nie jest dobre podejście... Czy ktoś podejmie się oceny takiego rozwiązania i ewnetualnie wskaże mi bardziej właściwą drogę?

Pozdrawiam
Tarcil
PS. Przepraszam, jeżeli wciąłem się w złym temacie.
Go to the top of the page
+Quote Post
Black-Berry
post
Post #8





Grupa: Zarejestrowani
Postów: 663
Pomógł: 6
Dołączył: 3.06.2007
Skąd: Kraków

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


Twój problem jest bardzo 'klasyczny'. Masz tak:
  1. <?php
  2. while($news = $query_news->fetchResults())
  3. ?>

a jeśli masz zagnieżdzenia powinieneś mieć tak:
  1. <?php
  2. $result =  $query_news->getResult();
  3. while($news = $query_news->fetchResults($result))
  4. ?>


A co do wyższych postów to na dalszym etapie prac przekonacie się że singletony to bagno w które lepiej się nie pakować. Było wiele wątków na ten temat. Zainteresujcie się rozwiązaniem za pomocą kontekstu;

Tarcil kombinujesz bez singletona ale coś masz nie tak; Zrób sobie plik Bootstrap.php a w nim:

  1. <?php
  2. function __autoload($class)
  3.    {
  4.        $class = str_replace('_', '/', $class);
  5.        require_once $class . '.php';
  6.    }
  7.    
  8.    //creating core objects...
  9.    $config = new Config();
  10.    $log = new Log();
  11.    $dbDriver = new Db_Driver();
  12.    $session = new Session();
  13.    $language = new Language();
  14.    $user = new User();
  15.    [b]$news= new News();[/b]
  16.    $router = new Router();
  17.    $buffer = new Buffer();
  18.    
  19.    //creating context...
  20.    $context = new Core_Context();
  21.    $context->setConfig($config);
  22.    $context->setLog($log);
  23.    $context->setDbDriver($dbDriver);
  24.    $context->setSession($session);
  25.    $context->setLanguage($language);
  26.    $context->setUser($user);
  27.    [b]$context->setNews($news);[/b]
  28.    $context->setRouter($router);
  29.    $context->setBuffer($buffer);
  30.    
  31.    //setting context...
  32.    $log->setContext($context);
  33.    $dbDriver->setContext($context);
  34.    $session->setContext($context);
  35.    $language->setContext($context);
  36.    $user->setContext($context);
  37.    [b]$news->setContext($context);[/b]
  38.    $router->setContext($context);
  39.    $buffer->setContext($context);
  40.    
  41.    //other...
  42.    $config->load(MAIN_PATH . 'config.ini');
  43.    $dbDriver->connect();
  44.    $dbDriver->query('SET NAMES `utf8`');
  45.    $language->initialize();
  46.   [b] $news->initialize();[/b]
  47. ?>


Ten post edytował Black-Berry 2.02.2009, 10:46:50


--------------------
Go to the top of the page
+Quote Post
Tarcil
post
Post #9





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

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


Dzięki smile.gif
Jak znajdę trochę czasu na przepisanie kodu to na pewno skorzystam smile.gif

Black-BerryChciałem Ci dać "Pomógł" ale nie widzę nigdzie odpowiedniego przycisku...

Pozdrawiam

Ten post edytował Tarcil 2.02.2009, 12:08:22
Go to the top of the page
+Quote Post
skowron-line
post
Post #10





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

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


Cytat(Tarcil @ 2.02.2009, 12:06:20 ) *
Black-BerryChciałem Ci dać "Pomógł" ale nie widzę nigdzie odpowiedniego przycisku...

I nie znajdziesz jeżeli nie jesteś autorem Wątku.


--------------------
I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy.

QueryBuilder, Mootools.net, bbcradio1::MistaJam
http://www.phpbench.com/
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 22.08.2025 - 09:20