Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: prezentowanie wyników w mysqli
Forum PHP.pl > Forum > PHP > Object-oriented programming
PawelC
Hej smile.gif Wreszcie udało mi się, nawiązać połączenie z bazą przy pomocy mysqli i wykorzystaniem połączenia do pobierania danych. Wrzuciłem połączenie i wybór bazy w konstruktor, bo jest on zawsze automatycznie ładowany, i w momencie pobierania danych narodziło się pytanie. Mam taki kod:
  1. <?php
  2.  
  3.  
  4.        class sqli
  5.            {
  6.                
  7.            public function __construct($host,$login,$haslo,$baza)
  8.            {
  9.                $this->mysqli=new mysqli($host,$login,$haslo,$baza);
  10.            }
  11.            
  12.            
  13.            
  14.            public function dane($query)
  15.            {
  16.                $result=$this->mysqli->query($this->query=$query);
  17.                while($data=$result->fetch_object()){
  18.                
  19.                    echo $data->kategoria;
  20.                }
  21.            }
  22.        
  23.            
  24.        }
  25.  
  26. $sqli=new sqli('localhost','root','','katalog');
  27. $sqli->dane("select kategoria from kategorie");
  28.  
  29. ?>

I teraz chodzi mi o pobieranie danych, czy za każdym razem muszę robić osobno takie coś:
  1. <?php
  2. public function dane($query)
  3.             {
  4.                 $result=$this->mysqli->query($this->query=$query);
  5.                 while($data=$result->fetch_object()){
  6.                
  7.                     echo $data->kategoria;
  8.                 }
  9. ?>

W tym kodzie powyżej pobieram nazwę kategorii, a teraz jakbym chciał pobrać podkategorie z innej tabeli, to muszę na nową stworzyć to samo, tyle że, ze zmienionymi danymi, czyli:
  1. <?php
  2. public function podkategorie($query)
  3.             {
  4.                 $result=$this->mysqli->query($this->query=$query);
  5.                 while($data=$result->fetch_object()){
  6.                
  7.                     echo $data->podkategoria;
  8.                 }
  9. ?>

Czy można to zrobić w jakiś inny sposób?
Polskie nazewnictwo funkcji stosuję tylko w celach pokazowych smile.gif
skowron-line
Zrób sobie jedna metode do pobierania danych z zapytania.

coś ala
  1. <?php
  2. public function dane( $query )
  3. {
  4. $q = mysqli->query( $query );
  5. return $q->fetch_object(); // zwroci Ci obiekty ktore sobie pozniej w petli wyswietlisz
  6. }
  7. ?>
PawelC
Zrobiłem coś na podobę jak napisałeś:
  1. <?php
  2. public function dane($query)
  3.            {
  4.                $result=$this->mysqli->query($this->query=$query);
  5.                return $result->fetch_object();
  6.            }
  7.                    
  8.            
  9.        
  10.  
  11. $sqli=new sqli('localhost','root','','katalog');
  12. foreach($sqli->dane("select kategoria from kategorie") as $key)
  13. {
  14.    echo $key;
  15. }
  16. ?>

I wszystko ładnie pięknie pobiera itp, ale wyświetla mi tylko jeden rekord!Dlaczego?
skowron-line
Kod
foreach($sqli->dane("select kategoria from kategorie") as $key)

Tak nie rob bo przy kazdym obruceniu sie petli bedzie sie to zapytane wykonywalo



  1. <?php
  2. $sqli=new sqli('localhost','root','','katalog');
  3. $x = $sqli->dane("select kategoria from kategorie");
  4. echo'<pre>';
  5. print_r( $x  );
  6. ?>


zobacz co będzie.
PawelC
Dostałem coś takiego:
  1. <?php
  2. stdClass Object
  3. (
  4.    [kategoria] => Biznes i Ekonomia
  5.  
  6. )
  7. ?>

Tylko dlaczego pobiera jeden rekord?
skowron-line
ponieważ element kategoria jest nadpisywany az do ostatniego
http://pl2.php.net/manual/pl/mysqli-stmt.fetch.php#83284 zobacz to
PawelC
Czarowałem i wymyśliłem coś takiego:
  1. <?php
  2. public function dane($query)
  3.            {
  4.                $result=$this->mysqli->prepare($this->query=$query);
  5.                $result->execute();
  6.                $result->bind_result($name);
  7.                    while ($result->fetch())
  8.                  {
  9.                    print ($name);
  10.                  }
  11.  
  12.            }
  13.                    
  14.            
  15.      }
  16. $sqli=new sqli('localhost','root','','katalog');
  17. $sqli->dane("select kategoria from kategorie");
  18. ?>


Wynik daje taki jaki chcę czyi:
Cytat
Biznes i Ekonomia Blogi Internetowe Domy i Nieruchomo?ciEdukacja i Nauka Firmy wg. Bran? Handel Elektroniczny Handel Tradycyjny Hobby Katalogi Stron / Firm Komputery i Internet Kultura i Sztuka Medycyna Motoryzacja Muzyka Og?oszenia, AukcjeRegionalne Rozrywka Sport i Turystyka Szko?y i Uczelnie Telefonia Zdrowie i Uroda Zwierz?ta


I teraz jest wszystko ładnie i pięknie he he, podany przykład pobiera tylko jedną kolumne z bazy, a co w wypadku pobierania kilku kolumn?
Wiem że mogę to zrobić tak:
  1. <?php
  2. public function dane($query)
  3.            {
  4.                $result=$this->mysqli->prepare($this->query=$query);
  5.                $result->execute();
  6.                $result->bind_result($name,$names);
  7.                    while ($result->fetch()) {
  8.                    
  9.                    print ($name.'<br />');
  10.                    print ($names);
  11.    }
  12.            }
  13. ?>

A jest jakiś bardziej optymalne rozwiązanie, żeby za każdym razem nie podawać ilości kolumn?
Bo przykładowo mam w bazie tabele, podkategorie, a w niej kolumny, id, podkategoria i kategoria, i teraz musiałbym przebudować, trochę kod dane($query);
Crozin
Genralnie możesz zrobić sobie dwie metody: getRow(), getRows() które działają mniej więcej tak:

getRow():
wykonuje zapytanie
zwraca fetchObject();

getRows():
deklarujesz sobie pustą tablicę
wykonujesz zapytanie
w pętli dopisujesz wynik fetchObject() jako kolejny element tablicy
zwracasz tablicę
PawelC
z getRow() to wymyśliłem coś takiego:
  1. <?php
  2. public function getRow($query)
  3.            {
  4.                $result=$this->mysqli->query($this->query=$query);
  5.                return $result->fetch_object();
  6.                
  7.            }
  8. ?>

Tak jak pisałeś, wykonuje zapytanie i zwraca fetch_object()
Z getRows()
coś takiego wyczarowałem:
  1. <?php
  2. public function getRows($query)
  3.            {
  4.                $dane=array();
  5.                $result=$this->mysqli->query($this->query=$query);
  6.                while($wynik=$result->fetch_object()){
  7.                    $data[]=$wynik;
  8.                    return $data;
  9.                    
  10.                }
  11.            }
  12. ?>

Fakt faktem zwraca id i nazwę kategorii smile.gif Tylko niewiem czy dobrze to zrobiłem, wynik mi zwraca w postaci:
  1. <?php
  2. Array (     [0] => stdClass Object         (             [id] => 1             [kategoria] => Biznes i Ekonomia          )  )
  3. ?>
Crozin
W getRow() możesz ograniczyć się do
  1. <?php
  2. public function getRow($query)
  3.           {
  4.               return $this->mysqli->query($this->query=$query)->fetch_object();
  5.           }
  6. ?>
getRows() zrobiłeś dobrze z tym, że return powinno być po pętli while(), nie w jej środku.
PawelC
A z tym ograniczeniem w getRow() to nawet nie wiedziałem że tak można, teraz już na przyszłość będę wiedział biggrin.gif

W getRows() wstawiłem return poza pętle i pobiera wszystkie kategorie wraz z ID smile.gif
Teraz mi daje taki wynik:
  1. <?php
  2. Array (     [0] => stdClass Object         (             [id] => 1             [kategoria] => Biznes i Ekonomia          )      [1] => stdClass Object         (             [id] => 2             [kategoria] => Blogi Internetowe          )      [2] => stdClass Object         (             [id] => 3             [kategoria] => Domy i Nieruchomo?ci         )
  3. ?>

czyli zadowalający i teraz rozumiem, że muszę przepuścić przez pętle tablice aby wyświetliło normalnie
czyli id kategoria, a nie tak jak wyżej jest.
Crozin
Tak.
  1. <?php
  2. $rows = $...->getRows('....');
  3. foreach($rows as $row){
  4.  echo $row->kategoria;
  5. }
  6. ?>
PawelC
Działa super, tak jak chciałem. I mam jeszcze jedno pytanie co powinna zawierać klasa do obsługi bazy danych? Domyślam się że najlepiej wszystko do obsługi konkretnej bazy.

Kolejne pytanie: jak rozwiązać w klasie update,insert i delete, stworzyć osobne metody?
Jak widać do wykonania zapytania używam takiego kodu:
  1. <?php
  2. $result=$this->mysqli->query($this->query=$query);
  3. ?>

I jedyne czym by się różniły metody, to komunikatem końcowym.
Crozin
Cytat
Działa super, tak jak chciałem. I mam jeszcze jedno pytanie co powinna zawierać klasa do obsługi bazy danych? Domyślam się że najlepiej wszystko do obsługi konkretnej bazy.
Nie. Ona jest bardzo abstrakcyjna/uniwersalna. Nie działa z żadną konkretną bazą. Oferuje jedynie zestaw metod ułatwijących innym częściom kodu (modelom) korzystanie z bazy.
Innymi słowy - lepiej korzystaj z PDO niż pisz własną klasę, bo to jest bez sensu - chyba, że robisz to jedynie w celach trenigowych
PawelC
Poczytam o PDO, w książce jest trochę o tym smile.gif
Klasę do obsługi bazy oczywiście piszę w celach treningowych, ponieważ na pisaniu czegoś najlepiej się uczyć, choćby dlatego że doświadczenie idzie nabyć podczas rozwiązywania takich problemów.

Dokończyłem klasę update, select i insert dałem na tej zasadzie:
  1. <?php
  2. public function update($query)
  3.            {
  4.                $result=$this->mysqli->query($this->query=$query);
  5.                if($result===true)
  6.                {
  7.                    echo "Dane zostały zaktualizowane!";
  8.                }
  9.                else {
  10.                    echo "Wystąpił błąd podczas aktualizowania danych!";
  11.                }
  12.            }
  13. ?>

Teraz czas napisać jakiś logger, który zapisze zapytanie do pliku i czas wykonania smile.gif
Crozin
No i to jest źle zrobione.
1) Po co mi takie komunikaty?
2) Jak wszystko poszło dobrze, to nie ma potrzeby niczego zwracać (może być zwykłe TRUE). Jak coś poszło źle to rzuć wyjątkiem, który nada się tu lepiej
3) Metody update/insert/delete to dobry pomysł w ORMach, ale w zwykłych "klasach obsługi baz danych" nie
PawelC
Cytat
3) Metody update/insert/delete to dobry pomysł w ORMach, ale w zwykłych "klasach obsługi baz danych" nie

To co mogę zrobić w zwykłej klasie, zamiast insert etc...
Cytat
1) Po co mi takie komunikaty?
2) Jak wszystko poszło dobrze, to nie ma potrzeby niczego zwracać (może być zwykłe TRUE). Jak coś poszło źle to rzuć wyjątkiem, który nada się tu lepiej

Wiem, komunikaty dałem tylko tak żeby sprawdzić czy działa smile.gif Normalnie ich niema, jest tylko w razie błędu.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.