Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Zend] Problem z joinem dwóch tabel
Forum PHP.pl > Forum > PHP > Frameworki
uraharu
Mam problem z konstrukcją zapytania do bazy mysql w Zendzie

mam takie zapytanie SQL
  1. SELECT * FROM wpisy WHERE tytul='$tytul' INNER JOIN uzytkownicy ON wpisy.autor = uzytkownicy.id;


Głównie chodzi o to aby pobrało informacje o użytkowniku danego wpisu z tabeli uzytkownicy, łącze je poprzez wpisanie identyfikatora autora do konkretnego wpisu

Jak takie zapytanie przerobić na zenda?

Zrobiłem coś takiego w kontrolerze
  1. $dbAdapter = Zend_Registry::get('dbAdapter'); //this is based on Akrabat's Tutorial - in the bootstrap file.
  2. $wpis = $dbAdapter->fetchAll("SELECT w.*, u.* FROM wpisy w JOIN uzytkownicy u WHERE w.tytul=$tytul");
  3. $this->view->wpis=$wpis;


korzystajac z poradnika http://wiki.ekini.net/main/Zend_db#Creatin...nside_the_Model
lecz w pętli w widoku wywala mi błąd

  1. <?php
  2. foreach($this->wpis as $wpis) {
  3.  
  4. echo '<tr>';
  5. echo '<td class="td2" rowspan="2">s</td>';
  6. echo ' <td class="td1">'.$wpis->data_dodania.'</td>';
  7. echo '</tr>';
  8. echo ' <tr>';
  9. echo '<td class="td3">'.$wpis->tresc.'</td>';
  10. echo ' </tr>';
  11.  
  12.  
  13. }
  14. ?>


Aplication Error

Jak wykonac takie połączenie tabeli aby mieć dane z jednej i drugiej?
zend
resources.frontController.params.displayExceptions = 1 pokaż cały komuniakt błędu, dodaj jeszcze klauzurę ON w join'ie
uraharu
to jest mój kod kontrolera akcji
  1. $tytul= $this->getRequest()->getParam('tytul');
  2. $dbAdapter = Zend_Registry::get('dbAdapter'); //this is based on Akrabat's Tutorial - in the bootstrap file.
  3. $wpis = $dbAdapter->fetchAll("SELECT w.*, u.* FROM wpisy w JOIN ON uzytkownicy u WHERE w.tytul=$tytul");
  4. $this->view->wpis=$wpis;


a błąd
Kod
An error occurred
Application error
Exception information:

Message: No entry is registered for key 'dbAdapter'
Stack trace:

#0 C:\wamp\www\forum\application\controllers\PostyController.php(18): Zend_Registry::get('dbAdapter')
#1 C:\wamp\php\library\Zend\Controller\Action.php(513): PostyController->pokazAction()
#2 C:\wamp\php\library\Zend\Controller\Dispatcher\Standard.php(295): Zend_Controller_Action->dispatch('pokazAction')
#3 C:\wamp\php\library\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#4 C:\wamp\php\library\Zend\Application\Bootstrap\Bootstrap.php(97): Zend_Controller_Front->dispatch()
#5 C:\wamp\php\library\Zend\Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
#6 C:\wamp\www\forum\public\index.php(26): Zend_Application->run()
#7 {main}  

Request Parameters:

array (
  'controller' => 'posty',
  'action' => 'pokaz',
  'tytul' => '2',
  'module' => 'default',
)

zend
Przecież pisze Ci wyraźnie że nie ustawiłeś połączenia do rejestru
uraharu
tak, ale w pliku application.ini mam ustawione

Kod
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "root"
resources.db.params.password = ""
resources.db.params.dbname = "zendforum"
resources.db.params.charset = "utf8"


jestem początkujący w zendzie, więc przepraszam jak coś głupiego napisze
zend
Dodaj jeszcze resources.db.isDefaultTableAdapter = true i pobieraj przez $db = Zend_Db_Table::getDefaultAdapter();
uraharu
dziękuję, błedu nie wywala ale wyświetla mi się teraz pusta strona
czy ten sposób pobrania danych jest ok?

  1. <?php
  2. foreach($this->wpis as $wpis) {
  3.  
  4. echo '<tr>';
  5. echo '<td class="td2" rowspan="2">s</td>';
  6. echo ' <td class="td1">'.$wpis->data_dodania.'</td>';
  7. echo '</tr>';
  8. echo ' <tr>';
  9. echo '<td class="td3">'.$wpis->tresc.'</td>';
  10. echo ' </tr>';
  11.  
  12.  
  13. }
  14. ?>
zend
Sam sprawdź, ale prawdopodobnie fetchujesz dane jako tablice a korzystasz jak z obiektu changing fetch mode
  1. echo '<pre>';
  2. print_r($this -> view -> wpisy);
  3. echo '</pre>';


Włącz też wyświetlanie błędów przez php. A tak wogóle to czemu wykonujesz zapytania w kontrolerze? Do tego są modele. Jeśli chcesz robić selecty to skorzystaj z $db -> select();
uraharu
w jaki sposób mógłbym włączyć to wyświetlanie błędów?

Bo cokolwiek wpisze w widoku pokaż to wyświetla mi się pusta strona :|
zend
Podstawy php ini_set('display_errors' , 'On'); w index.php, policz też count czy cokolwiek masz do wyświetlenia
uraharu
dodałem wyświetlanie błędów do pliku index.php, lecz nadal mam białą stronę nic mi się nie wyświetla
zrobiłem count($wpis) lecz nie mam jak sprawdzić gdy mam pustą stronę
zend
No to zrób to w kontrolerze a widok zakomentuj, albo wyświetl zapytanie i wykonaj w phpMyAdmin'ie i będziesz znał efekty
uraharu
zakomentowałem wszystkie zmienne co przekazuje do widoku, przekazałem tylko $ile
$ile=count($wpis);
i nadal mam pustą stronę

chyba jest problem z zapytaniem
ale zmieniłem na inne aby sprawdzić czy zadziała

  1. SELECT * FROM wpisy INNER JOIN uzytkownicy ON wpisy.autor= uzytkownicy.id


w phpmyadminie działa i zwraca mi 3 wiersze natomiast w zendzie pusto, biała strona
zend
Zakomentuj WIDOK, cały, bo tam może być błąd, a nie zmienne które tam przekazujesz! Pisałem Ci że $wpis to nie obiekt tylko tablica, więc używaj jak tablicy $wpis['kolumna']. Zdumpuj wyniki zapytania (pisałem o tym już wcześniej).
uraharu
zakomentowałem cały widok, nie może być tam błędu bo mam tylko

  1. <?php
  2. //print_r($this -> view -> wpis);
  3. ?>


i odwoływałem się do niego jako do tablicy to nic nie dało, cały czas mam pustą stronę
wyświetlanie błędów również włączyłem

również zdumpowałem wynik zapytania w kontrolerze i nadal to samo
zend
Ustaw sobie error_reporting na wszystko. A jak nie pomoże to komentuj swój kod i wyświetlaj coś echo aż zaskoczy. Możesz też dać echo na końcu index.php
uraharu
problem jest z zapytaniem SQL bo zakomentowaniu sql wszystko działa jak należy

  1. public function pokazAction() {
  2. $tytul= $this->getRequest()->getParam('tytul');
  3. $db = Zend_Db_Table::setDefaultAdapter($dbAdapter);
  4. $wpis = $dbAdapter->fetchAll("SELECT w.*, u.* FROM wpisy w JOIN ON uzytkownicy u WHERE w.tytul= $tytul");
  5. }

zend
Podajesz tytuł? Zabezpieczaj dane $db -> quoteInto(); Spróbuj $this -> _getParam('tytul' , 'bleble');
uraharu
ok, spróbuje to w inny sposób zrobić
znalazłem coś takiego na stronie zenda

  1. 1.
  2. // Build this query:
  3. 2.
  4. // SELECT p."product_id", p."product_name"
  5. 3.
  6. // FROM "products" AS p JOIN "line_items" AS l
  7. 4.
  8. // ON p.product_id = l.product_id
  9. 5.
  10.  
  11. 6.
  12. $select = $db->select()
  13. 7.
  14. ->from(array('p' => 'products'),
  15. 8.
  16. array('product_id', 'product_name'))
  17. 9.
  18. ->join(array('l' => 'line_items'),
  19. 10.
  20. 'p.product_id = l.product_id',
  21. 11.
  22. array() ); // empty list of columns


tylko co wpisać do modelu aby połączyło z jedną i drugą tabelą?
zend
No jak co? Nazwe tabeli i pola po których się łączy, instancje obiektu możesz przezazywać do metody łączącej, ustawiasz $select -> setIntegrityCheck(false); a nazwe tabeli nasz w $table -> info();
uraharu
mam tak

kontroler:
  1. $mdl=new Forum_Model_Wpisy();
  2.  
  3. $select = $mdl->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
  4. ->setIntegrityCheck(false);
  5. $select = $mdl->select()
  6. ->from(array('w' => 'wpisy'), array('id','tytul','tresc','kategoria','autor','data_dodania'))
  7. ->join(array('u' => 'uzytkownicy'), 'w.autor = u.id');
  8. $wpis= $mdl->fetchAll($select);
  9. $this->view->wpis=$wpis;
  10.  
  11. $wpis = $db->fetchRow($select);
  12. $this->view->wpis=$wpis;


i model

  1. <?php
  2. class Forum_Model_Wpisy extends Zend_Db_Table_Abstract {
  3.  
  4.  
  5. protected $_name = 'wpisy';
  6.  
  7. }


i wywala mi błąd
Kod
Application error
Exception information:

Message: Select query cannot join with another table
Stack trace:

#0 C:\wamp\php\library\Zend\Db\Adapter\Abstract.php(456): Zend_Db_Table_Select->assemble()
#1 C:\wamp\php\library\Zend\Db\Adapter\Pdo\Abstract.php(238): Zend_Db_Adapter_Abstract->query(Object(Zend_Db_Table_Select), Array)
#2 C:\wamp\php\library\Zend\Db\Table\Abstract.php(1505): Zend_Db_Adapter_Pdo_Abstract->query(Object(Zend_Db_Table_Select))
#3 C:\wamp\php\library\Zend\Db\Table\Abstract.php(1321): Zend_Db_Table_Abstract->_fetch(Object(Zend_Db_Table_Select))
#4 C:\wamp\www\forum\application\controllers\PostyController.php(31): Zend_Db_Table_Abstract->fetchAll(Object(Zend_Db_Table_Select))
#5 C:\wamp\php\library\Zend\Controller\Action.php(513): PostyController->pokazAction()
#6 C:\wamp\php\library\Zend\Controller\Dispatcher\Standard.php(295): Zend_Controller_Action->dispatch('pokazAction')
#7 C:\wamp\php\library\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#8 C:\wamp\php\library\Zend\Application\Bootstrap\Bootstrap.php(97): Zend_Controller_Front->dispatch()
#9 C:\wamp\php\library\Zend\Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
#10 C:\wamp\www\forum\public\index.php(26): Zend_Application->run()
#11 {main}  

Request Parameters:

array (
  'controller' => 'posty',
  'action' => 'pokaz',
  'tytul' => '2',
  'module' => 'default',
)


sądzę, że czegoś mi brakuje w modelu do połączenia z drugą tabelą ale jak to wykonać?
Pilsener
Przeczytałeś w ogóle dokumentację?
http://framework.zend.com/manual/en/zend.db.select.html
Znasz różnicę pomiędzy widokiem, modelem a kontrolerem? W kontrolerze tworzysz tylko nowy obiekt i wywołujesz odpowiednią metodę:
  1. $obiekt = new Model_Dane();
  2. $dane = $obiekt->pobierzDane();


Zapytania do bazy tworzysz w modelu, tworząc metodę "pobierzDane":
  1. public function pobierzDane(){
  2. $select = $this->select();
  3. $select->setIntegrityCheck(false);
  4. //i tak dalej
  5. return $select;
  6. }


Wszystko masz opisane w dokumentacji.
uraharu
zrobiłem tak jak pisałeś

model

  1. <?php
  2. class Forum_Model_Wpisy extends Zend_Db_Table_Abstract {
  3.  
  4.  
  5. protected $_name = 'wpisy';
  6.  
  7. public function pobierzDane() {
  8. $select = $this->select();
  9. $select->setIntegrityCheck(false);
  10. $select = $this->select()
  11. ->from(array('w' => 'wpisy'), array('id','tytul','tresc','kategoria','autor','data_dodania'))
  12. ->join(array('u' => 'uzytkownicy'), 'w.autor = u.id');
  13. $wpis= $this->fetchAll($select);
  14. return $select;
  15. }
  16.  
  17. }


i kontroler
  1. public function pokazAction() {
  2.  
  3. $mdl=new Forum_Model_Wpisy();
  4. $wpis = $mdl->pobierzDane();
  5. $this->view->wpis=$wpis;
  6. }


lecz mam ten sam błąd

Kod
Exception information:

Message: Select query cannot join with another table
Stack trace:

#0 C:\wamp\php\library\Zend\Db\Adapter\Abstract.php(456): Zend_Db_Table_Select->assemble()
#1 C:\wamp\php\library\Zend\Db\Adapter\Pdo\Abstract.php(238): Zend_Db_Adapter_Abstract->query(Object(Zend_Db_Table_Select), Array)
#2 C:\wamp\php\library\Zend\Db\Table\Abstract.php(1505): Zend_Db_Adapter_Pdo_Abstract->query(Object(Zend_Db_Table_Select))
#3 C:\wamp\php\library\Zend\Db\Table\Abstract.php(1321): Zend_Db_Table_Abstract->_fetch(Object(Zend_Db_Table_Select))
#4 C:\wamp\www\forum\application\models\Wpisy.php(14): Zend_Db_Table_Abstract->fetchAll(Object(Zend_Db_Table_Select))
#5 C:\wamp\www\forum\application\controllers\PostyController.php(35): Forum_Model_Wpisy->pobierzDane()
#6 C:\wamp\php\library\Zend\Controller\Action.php(513): PostyController->pokazAction()
#7 C:\wamp\php\library\Zend\Controller\Dispatcher\Standard.php(295): Zend_Controller_Action->dispatch('pokazAction')
#8 C:\wamp\php\library\Zend\Controller\Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#9 C:\wamp\php\library\Zend\Application\Bootstrap\Bootstrap.php(97): Zend_Controller_Front->dispatch()
#10 C:\wamp\php\library\Zend\Application.php(366): Zend_Application_Bootstrap_Bootstrap->run()
#11 C:\wamp\www\forum\public\index.php(26): Zend_Application->run()
#12 {main}  

Request Parameters:

array (
  'controller' => 'posty',
  'action' => 'pokaz',
  'tytul' => '2',
  'module' => 'default',
)
zend
Bo operacje wykonujesz na dwóch instancjach obiektu!
  1. $selelect = $this -> select()
  2. -> setIntegrityCheck(false)
  3. -> join();
  4.  
  5. return $this -> fetchAll($select);
uraharu
działa (: dziękuję bardzo

wystarczyło przenieść niżej jedną linijkę kodu
-> SetIntegrityCheck(false)

  1.  
  2. public function pobierzDane($tytul) {
  3. $select = $this->select();
  4. $select = $this->select()
  5. ->from('wpisy')
  6. ->where('wpisy.tytul= ?',$tytul)
  7. ->setIntegrityCheck(false)
  8. ->join('uzytkownicy', 'wpisy.autor = uzytkownicy.id');
  9. return $this -> fetchAll($select);
  10. }
  11.  

zend
Wywal pierwszą linijkę metody, bo niepotrzebnie zajmujesz pamięć tworząc obiekt z którego nie korzystasz
uraharu
wywaliłem dziękuję
a jeszcze mam takie pytanie odnośnie Zend_auth
jak pobrać z bazy danych identyfikator aktualnie zalogowanego użytkownika?

moje logowanie wyglada tak
  1. public function loginAction() {
  2. $form = new Forum_Form_Login();
  3. $form->setAction('/uzytkownik/login');
  4. $this->view->form = $form;
  5.  
  6. if($this->getRequest()->isPost() && $form->isValid($_POST)) {
  7. $dane = $form->getValues();
  8. $db = Zend_Db_Table::getDefaultAdapter();
  9. $authAdapter = new Zend_Auth_Adapter_DbTable(
  10. $db, 'uzytkownicy', 'login', 'haslo');
  11. $authAdapter->setIdentity($dane['user']);
  12. $authAdapter->setCredential($dane['pass']);
  13.  
  14. $result = $authAdapter->authenticate();
  15. if($result->isValid()) {
  16. $daneUzytkownika = $authAdapter->getResultRowObject();
  17. Zend_Auth::getInstance()->getStorage()->write($daneUzytkownika);
  18. $this->_helper->redirector('index', 'index');
  19. } else {
  20. $this->view->komunikat = 'Logowanie nieudane';
  21. }
  22. }
  23. }
Pilsener
http://framework.zend.com/manual/en/zend.a...troduction.html - masz tam opisane, za pobranie parametrów odpowiada metoda getIdentity():

  1. $auth = Zend_Auth::getInstance();
  2. echo $auth->getIdentity()->userid_albo_inny_id_czy_co_tam_masz_w_bazie_i_sesji;


A możesz to przejrzeć poprzez:
  1. Zend_Debug::dump($auth->getIdentity());


Zależy od tego, jak wygląda tabela "users", która trafia do sesji, nie ma sensu co chwila odpytywać bazę po ID usera, jego mail czy nie wiadomo co. Wszystko poza haszem hasła powinno być w sesji a dostęp do tego przez getIdentity().
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.