Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [zend] wyswietlanie polaczonych danych z dwoch tabell
Forum PHP.pl > Forum > PHP > Frameworki
nieraczek
Odnośnie tego co pisał batman i thm w innym moim poście chciałbym zrobić teraz poprawne pod względem technicznym wyświetlanie połączonych danych z dwóch tabel.

Powiem co zrobiłem:

W folderze 'models' utworzyłem pliki:

Ksiazki.php:
Kod
<?php

class Ksiazki extends Zend_Db_Table
{
    protected $_name = 'ksiazki';

    protected $_primary = 'id_ksiazki';
}


Autorzy.php:
Kod
<?php

class Autorzy extends Zend_Db_Table
{
    protected $_name = 'autorzy';

    protected $_primary = 'id_autora';
}


Natomiast w pliku IndexController.php mam:
Kod
    public function indexAction()
    {
        $db = Zend_Registry::get('dbAdapter');

        $select = $db->select()
             ->from(array('k' => 'ksiazki'))
             ->join(array('a' => 'autorzy'),
             'k.id_autora = a.id_autora');

        $this->view->lista = $db->fetchAll($select);
    }



A w innym pliku wyświetlam wyniki zapytania. Wszystko działa, ale jak widzicie w pliku 'IndexController.php' nie robię chyba zbyt poprawnym sposobem przynajmniej takie odniosłem wrażenie po wypowiedzi batmana i thm??

Więc jak to powinno wyglądać prawidłowo ? Jak rozumiem powinno być w pliku IndexController.php coś takiego:
Kod
    public function indexAction()
    {
               $ksiazkiTabela = new Ksiazki();
               $autorzyTabela = new Autorzy();

    }


Ale co dalej - jak zrobić SELECTA ? Bo jak zrobię tak jak na tej stronie: http://framework.zend.com/manual/en/zend.d...t.building.join

// Create the Zend_Db_Select object
$select = $db->select();

to wrócę przecież do tego sposobu wyświetlania, który mam obecnie, a który nie jest podobno poprawny.
batman
Jak to powinno wyglądać u Ciebie.
1. W kontrolerze tworzysz obiekt modelu Książki
2. W modelu Książki dodajesz metodę getBooksWithAuthors.
3. W nowej metodzie wykonujesz zapytanie i zwracasz wyniki.

  1. <?php
  2. public function getBooksWithAuthors() {
  3.    $this->select()->join(.......);
  4.    return $this->fetchAll($select);
  5. }
  6. ?>
nieraczek
W modelu Ksiazki zrobiłem tak:
Kod
public function getBooksWithAuthors()
    {
           $this->select()
             ->from(array('k' => 'ksiazki'))
             ->join(array('a' => 'autorzy'),
                    'k.id_autora = a.id_autora');
           return $this->fetchAll($select);
    }


W kontrolerze tak:
Kod
$ksiazkiTabela = new KsiazkiTable();
        
$this->view->lista = $ksiazkiTabela->getBooksWithAuthors();


Jednak
Kod
var_dump($this->lista);
zwraca mi NULL. W tej funkcji getBooksWithAuthors() chyba coś nie tak z zapytaniem ?


A może jednak to niemożliwe żeby w modelu, który odpowiada za tabelę Ksiazki pobrać takze dane z tabeli Autorzy ? Bo na tej stronie jest opisana metoda taką jak robiłem poprzednio i określona mianem 'najlepszej praktyki': http://wiki.ekini.net/main/Zend_db
Kod
Best Practices
[edit] What is the best way to do queries in Zend Framework?

Please see this blog post http://blog.ekini.net/2008/02/12/what-is-the-safest-way-to-do-database-queries-in-zend-framework/

//Roman Nestertsov's way of doing it.
$db = Zend_Registry::get(’dbAdapter’);
$sql = $db->quoteInto(”SELECT * FROM Table1 WHERE id = ?”, $target_id);

//Erik's way of doing it.
$db = Zend_Registry::get(’dbAdapter’);

$select = $db->select()->
          from(’Table1′, ‘*’)->
          where(’id = ?’, $id)->
          where(’url = ?’, $url);

$row = $db->fetchRow($select);


Czyli tak jak robiłem poprzednio. Ale z drugiej strony wtedy nie potrzebne byłyby modele, czyli jednak jakoś powinno się to dać zrobić w klasie, tylko jak ?
batman
Cytat
W modelu Ksiazki zrobiłem tak:

Zwraca Ci NULL ponieważ do fetchAll przekazujesz zmienną, która nie zawiera zapytania. Dziwne, że nie zgłosiło Ci błędu lub ostrzeżenia.
Zrób tak:
  1. <?php
  2. public function getBooksWithAuthors() {
  3.    $select = $this->select()
  4.             ->join(array('a' => 'autorzy'), 'k.id_autora = a.id_autora');
  5.    return $this->fetchAll($select);
  6. }
  7. ?>

Jeśli nadal będzie zwracało NULL, to przed return wstaw echo $select i zobacz co Ci za SQL-a skleiło.
nieraczek
  1. <?php
  2. An error occurred
  3. Application error
  4. Exception information:
  5.  
  6. Message: Select query cannot join with another table
  7. ?>



Jak zamiast aliasu 'k' użyję całej nazwy tabeli to też jest ten sam błąd:
Kod
public function getBooksWithAuthors()
    {
            $select = $this->select()
            ->join(array('a' => 'autorzy'), 'ksiazki.id_autora = a.id_autora');
           return $this->fetchAll($select);
    }



Może faktycznie nie można w klasie odpowiedzialnej za tabelę używać zapytania z JOIN'em. Tylko wówczas oznaczałoby to poważne ograniczenie w modelach ZF i to, że nadają się one tylko do zwracania wyników zapytania tej tabeli której dotyczy dany model hm......
batman
Sądziłem, że ten sposób zadziała. Skoro nie działa, to zadziała ten
  1. <?php
  2. $select = $this->getAdapter()->select();
  3. $select->from(array('k' => 'ksiazki'))->join(array('a' => 'autorzy'), 'k.id_autora = a.id_autora');
  4. ?>
nieraczek
hm.......

Obojętnie czy mam:
  1. <?php
  2. public function getBooksWithAuthors()
  3.    {
  4.  
  5.         $select = $this->getAdapter()->select();
  6. $select->from(array('k' => 'ksiazki'))->join(array('a' => 'autorzy'), 'k.id_autora = a.id_autora');
  7.  
  8.           return $this->fetchAll($select);
  9.    }
  10. ?>



czy
  1. <?php
  2. $st = $this->getAdapter()->query("SELECT * FROM ksiazki k JOIN autorzy a ON k.id_autora=a.id_autora");
  3. return $this->fetchAll($st);
  4. ?>


czy
  1. <?php
  2. $st = $this->getAdapter()->query('SELECT * FROM ksiazki');
  3. return $this->fetchAll($st);
  4. ?>



to i tak dostaję komunikat:
Kod
An error occurred
Application error
Exception information:

Message: SQLSTATE[42000]: Syntax error or access violation: 1064 Something is wrong in your syntax obok '' w linii 1
batman
Zrób echo ze zmiennej $select i wykonaj je w pgadminie/phpmyadminie. Nie możliwe, by to nie działało.
nieraczek
Dziwne, bo jeden sposób nie działa, a drugi który opisałem niżej działa questionmark.gif

Więc w modelu mam:
  1. <?php
  2. $select = $this->getAdapter()->select();
  3. $select->from(array('k' => 'ksiazki'))->join(array('a' => 'autorzy'), 'k.id_autora = a.id_autora');
  4.  
  5. return $this->fetchAll($select);
  6. ?>


W kontrolerze:
  1. <?php
  2. $ksiazki = new Ksiazki();
  3. $this->view->lista = $ksiazki->getBooksWithAuthors();
  4. ?>


echo selecta dało wynik:
Kod
SELECT `k`.*, `a`.* FROM `ksiazki` AS `k` INNER JOIN `autorzy` AS `a` ON k.id_autora = a.id_autora




Ale jak w modelu zrobię tak:
  1. <?php
  2. $select = $this->getAdapter()->query("SELECT * FROM ksiazki k JOIN autorzy a ON k.id_autora=a.id_autora");
  3. return $select;
  4. ?>


A w kontrolerze tak:
  1. <?php
  2. $ksiazki = new Ksiazki();
  3. $this->view->lista = $ksiazki->getBooksWithAuthors()->fetchAll();
  4. ?>


To wszystko działa i poprawnie się wyświetla, jednak nie rozumiem czemu tamten sposób nie działa, nawet jak w tamtym sposobie tak jak tu zwrócę $select i w kontrolerze tak jak tu zrobię fetchAll() to i tak nie działa, ta funkcja select() ZF ma jakieś błędy czy co ?
bigZbig
Bo za pierwszym razem próbujesz wykonać

Kod
$this->fetchAll($select);

a za drugim wykonujesz
Kod
$select->fetchAll();
batman
Masz jakieś dziwne problemy. U mnie działa to bez żadnych cyrków winksmiley.jpg
Możliwe, że jest jakiś błąd w ZF, możliwe jest też to, że z powodu błędu w kodowaniu danych wysyłanych do bazy i samej bazy. Powodów może być wiele.


edit

@bigZbig
To nie ma znaczenia, w takim sensie jak Ty to podajesz. Jednak Twój post nakierował mnie na problem.

Wstaw do modelu i będzie działać. Nie zauważyłem, że robisz fetchAll na obiekcie modelu, a nie na adapterze.
  1. <?php
  2. $select = $this->getAdapter()->select();
  3. $select->from(array('k' => 'ksiazki'))->join(array('a' => 'autorzy'), 'k.id_autora = a.id_autora');
  4. return $this->getAdapter()->fetchAll($select);
  5. ?>
nieraczek
lol - faktycznie, zrobiłem tak jak napisał batman i teraz działa - dzięki batman i bigZbig - dam Wam obu 'pomogl' smile.gif
MakeArt
Witam mam problem...wzorowałem się na tym wątku i w modelu mam
  1. <?php
  2. class Projekty extends Zend_Db_Table {
  3.       protected $select = 'projekty';
  4.      
  5.    public function getProjektyRodzajProjektu() {
  6.              
  7.        $select = $this->getAdapter()->select();
  8.        $select->from(array('p' => 'projekty'))->join(array('r' => 'rodzajprojektu'), 'p.IdRodzaju = r.IdRodzaju');
  9.        return $this->getAdapter()->fetchAll($select);
  10.        
  11.    }
  12. }
  13. ?>


a w kontrolerze akcje details
  1. <?php
  2. function detailsAction() {
  3.      $this->view->title = "Szczegóły";
  4.              $model= new Projekty();
  5.            $this->view->projekty = $model->getProjektyRodzajProjektu();
  6.   }
  7. ?>

i nic pusto... zwraca pustą tablice... zapytanie generowane przez model działa w phpmyadmin. Zrobiłem jakiś oczywisty błąd?? Poprzednie sposoby także zwracają mi pustą tablice....
batman
Zamiast
  1. <?php
  2. protected $select = 'projekty';
  3. ?>
powinno być
  1. <?php
  2. protected $_name = 'projekty';
  3. ?>
. Ale to nie powinno być przyczyną problemów.
Wstaw przed return
  1. <?php
  2. echo $select;
  3. ?>
. Wówczas wykonaj zapytanie, które się wyświetli w phpmyadmin/pgadmin i zobacz czy też zwróci pusty wynik.
MakeArt
już to robiłem... zapytanie jest dobre.
batman
Cytat
zapytanie jest dobre

Czyli zwróciło jakieś wiersze? Jeśli tak, to
  1. <?php
  2. Zend_Debug::dump($model->getProjektyRodzajProjektu());
  3. ?>

i zobacz co się wyświetli.
MakeArt
Dzieki. kurcze zwraca...
  1. <?php
  2. array(2) {
  3.  [0] => array(5) {
  4.    ["IdProjektu"] => string(1) "1"
  5.    ["Tytul"] => string(51) "Aplikacja wspomagająca badania literaturowe BadLit"
  6.    ["DataUtworzenia"] => string(10) "2008-10-15"
  7.    ["IdRodzaju"] => string(1) "1"
  8.    ["NazwaRodzaju"] => string(29) "Praca dyplomowa - in?ynierska"
  9.  }
  10.  [1] => array(5) {
  11.    ["IdProjektu"] => string(2) "23"
  12.    ["Tytul"] => string(19) "Suwnica przemys?owa"
  13.    ["DataUtworzenia"] => string(10) "0000-00-00"
  14.    ["IdRodzaju"] => string(1) "2"
  15.    ["NazwaRodzaju"] => string(29) "Praca dyplomowa - licencjacka"
  16.  }
  17. }
  18. ?>

Mam podpięte SMARTY, może w tym jest problem i muszę wyświetlać to innym sposobem niż do tej pory
zwykłe $model->fetchAll().


Namieszałem ze smartym dlatego nie wyświetlało. Dzięki za pomoc!!
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.