Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [ZF] Pobieranie danych i wyświetlanie, w 2 pętlach równolegle
IceManSpy
post
Post #1





Grupa: Zarejestrowani
Postów: 1 006
Pomógł: 111
Dołączył: 23.07.2010
Skąd: Kraków

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


Witam

Mam pewien problem, który nie wiem jak rozwiązać. Mam model i tablę w bazie odpowiadającą za prywatne wiadomości. Pole od (nadawca) i do (adresat) są jako int - numer ID usera.
W modelu mam metodę pobierającą wszystkie wiadomości. Wszystko jest ok, tylko nie wiem jak napisać wyświetlanie danych usera (login) przy polu nadawcy.
Nie mogę napisać pola do, bo potrzebuje jego ID do wysłania np odpowiedzi.

Aktualnie mam zrobione tak, że pobieram całą listę w kontrolerze, przekazuje do widoku a w widoku pobieram metodą PobierzLogin z modelu wiadomości login i wyświetlam. Ale takie rozwiązanie nie może być, bo przecież model nie powinien być w widoku.

Chciałbym pobrać wszystkie wiadomości, potem puścić pętle (foreach / while ? ) aby odczytał login usera i dodał kolejną wartość do tablicy. Nie wiem ja kto zrobić :/ Wiadomości pobieram przez fetchAll.
Go to the top of the page
+Quote Post
melkorm
post
Post #2





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

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


Jak masz zapytanie odnośnie wiadomości to możesz :
  1. $usersIds = array();
  2. foreach($messages as $m)
  3. {
  4. $usersIds[ $m['idFrom'] ] = $m['idFrom'];
  5. $usersIds[ $m['idTo'] ] = $m['idTo'];
  6. }
  7.  
  8. // później takie quey: (z warunkiem czy przypadkiem usersIds nie jest puste - inaczej dostaniesz wyjątkiem
  9. $this->fetchPairs(
  10. $this->select()->from('users', array('idUser', 'login'))->where('idUser IN (?)', $usersIds)
  11. );
  12.  
  13. // zrób sobei var dump'a a zobaczysz coś w stylu:
  14. 5 => 'login'
  15. ....
  16. ); // gdzie klucz tablicy to idUser'a a wartość to login
  17.  
  18. // i wtedy tylko przekazać to do widoku
  19. // i jak masz pętle to odpowiednio podstawić pod klucz tablicy
  20.  


Oczywiście mógłbyś zrobić 2 razy JOIN'a ale sądzę że dwa zapytania będą szybsze, chociaż nigdy tego nie testowałem, więc jak się Tobie nudzi możesz potestwoać i zaprezentować wyniki =D

PS. Metoda fetchPairs jest dostępna z poziomu $this->_db .

Ten post edytował melkorm 28.08.2011, 11:33:31
Go to the top of the page
+Quote Post
IceManSpy
post
Post #3





Grupa: Zarejestrowani
Postów: 1 006
Pomógł: 111
Dołączył: 23.07.2010
Skąd: Kraków

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


Problem jest taki, że mam 3 typy userów i dla każdego z nich jest inna tabela. Taka musi być. W tabeli user mam typ usera.
Mam metodę pobierającą dane na podstawie numeru ID usera.
Teraz bym chciał zrobić jakiegoś foreacha, w którym wywołam tą metodę na podstawie numeru ID usera i dopisze mi do tablicy tą daną jako jakaś tam zmienna.
Join także odpada, chyba że w modelu robić joina w zależności od typu użytkownika tak jak teraz to robię:
  1. public function getName($user_id)
  2. {
  3. /**
  4.   * Pobieram główny adapter bazy danych
  5.   */
  6. $db = $this->getDefaultAdapter();
  7. /**
  8.   * Pobieram typ konta dla usera o ID przekazanym w paramterze
  9.   */
  10. $query = $db->select()->from('user',array('use_role'))->where('use_pk_id=?',$user_id);
  11. $fetch_role = $db->fetchAll($query);
  12. $role = $fetch_role[0]['use_role'];
  13. /**
  14.   * Wg roli usera wykonuje zapytanie do odpowiedniej tabeli i zwracam imie i nazwisko
  15.   */
  16. switch($role){
  17. case 'student':
  18. $query = $db->select()->from('student',array('stu_name','stu_surname'))->where('use_id=?',$user_id);
  19. $fetch_name = $db->fetchAll($query);
  20. $name = $fetch_name[0]['stu_name']." ".$fetch_name[0]['stu_surname'];
  21. return $name;
  22. break;
  23. case 'administrator':
  24. $query = $db->select()->from('administrator',array('adm_name','adm_surname'))->where('use_id=?',$user_id);
  25. $fetch_name = $db->fetchAll($query);
  26. $name = $fetch_name[0]['adm_name']." ".$fetch_name[0]['adm_surname'];
  27. return $name;
  28. break;
  29. case 'professor':
  30. default:
  31. $query = $db->select()->from('professor',array('pro_name','pro_surname'))->where('use_id=?',$user_id);
  32. $fetch_name = $db->fetchAll($query);
  33. $name = $fetch_name[0]['pro_name']." ".$fetch_name[0]['pro_surname'];
  34. return $name;
  35. break;
  36. }
  37. }
Go to the top of the page
+Quote Post
melkorm
post
Post #4





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

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


No więc, nie czepiaj się samego modelu bazy danych - jeżeli twierdzisz że tak musi być, no to musi być (IMG:style_emoticons/default/wink.gif)

  1. $db = $this->getDefaultAdapter();

1. To jest nie potrzebne, tą samą funkcjonalnosć masz via $this

2. Przy takim modelu danych to będzie wtedy coś w stylu:
  1. $studentsIds = array();
  2. $adminsIds = array();
  3. $proffesorsIds = array();
  4.  
  5. $query = $db->select()->from('user',array('use_role'))->where('use_pk_id IN (?)',$ids); // ids to id'ki z poprzedniego mojego kodu
  6. $users = $db->fetchAll($query);
  7. forach( $users as $u)
  8. {
  9. // sprawdzasz typ i przypisujesz id do odpowiedniej tablicy
  10. }
  11. // no i tutaj robisz 1 (!) zapytanie z UNION na te 3 tabele z użytkownikami
  12. // gdzie w każdym UNION dajesz odpowiedni warunek na id - usera po typie


Dzięki temu masz 2 zapytania, a nie jakbyś chciał to zrobić w pętli gdzie masz zapytań: ilość userów * 2.
Go to the top of the page
+Quote Post
IceManSpy
post
Post #5





Grupa: Zarejestrowani
Postów: 1 006
Pomógł: 111
Dołączył: 23.07.2010
Skąd: Kraków

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


Staram się to zrozumieć... Do 6 linijki jest jasne. W tym foreachu przypisuje nr ID usera do poszczególnych tablic (case'a zrobię). A potem jakie mam zrobić zapytanie z UNION? Coś takiego:
  1. SELECT * FROM student WHERE id = 10 UNION SELECT * FROM professor WHERE id = 10 UNION SELECT * FROM administrator WHERE id = 10

Tylko wtedy mi zwróci admina, studenta i profesora o danym ID.
Trochę się tutaj pogubiłem :/

Dokładnie mam tak:
* model:
  1. // wysłane wiadomości
  2. public function showSendMessage($user_id)
  3. {
  4. $query = $this->select()->where('mes_from = ?',$user_id)->where('mes_del_from=?',0);
  5. return $this->fetchAll($query);
  6. }

*kontroler:
  1. $message = new Model_Message();
  2. $this->view->message = $message->showSendMessage($this->user_id); //$this->id to jest numer ID usera

*widok:
  1. <?php foreach($this->message as $message):?>
  2. //wyświetlam sobie w pętli
  3. <td><?php echo $message->mes_topic; ?></td>
  4. <td><?php echo $message->mes_sendtime; ?></td>
  5. <?php endforeach; ?>
Go to the top of the page
+Quote Post
melkorm
post
Post #6





Grupa: Zarejestrowani
Postów: 1 366
Pomógł: 261
Dołączył: 23.09.2008
Skąd: Bydgoszcz

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


No jeżeli masz 30 wiadomości, to Tobie produkuje 60'idków - przypisujesz je do tablic (jako klucz dajesz idUsera by nie robić array_unique) i wtedy masz zapytanie z IN dla każdego union i wtedy pobierzesz wszystkich użytkowników od razu i wtedy iterujesz po wynikach i tworzysz sobie tabelkę id=>dane użytkownika.
Go to the top of the page
+Quote Post
IceManSpy
post
Post #7





Grupa: Zarejestrowani
Postów: 1 006
Pomógł: 111
Dołączył: 23.07.2010
Skąd: Kraków

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


Nie wiem czy nie zrobię jak wcześniej z pobieraniem nazwy, czyli 1 zapytanie do pobrania roli użytkownika na podstawie numeru ID, a potem switch->case i w zależności od tej roli wykona się odpowiednie zapytanie. Tylko wtedy będzie tyle zapytań ile wiadomości :/
Bo trochę nie kumam tych pętli z odpowiednimi ID.

Wymyśliłem takie zapytanie:
  1. SELECT message.* , a.adm_name AS name , p.pro_name AS name, s.stu_name AS name
  2. FROM message
  3. LEFT JOIN administrator a
  4. ON a.use_id = message.mes_from
  5. LEFT JOIN professor p
  6. ON p.use_id = message.mes_from
  7. LEFT JOIN student s
  8. ON s.use_id = message.mes_from
  9. WHERE message.mes_from = 8 /* numer ID usera*/

I to zapytanie spełnia moje oczekiwania gdyby nie to, że pojawiają mi się kolumny name, name1 i name2. Jakby dało się te 3 kolumny zebrać jakoś w jedną o nazwie name, to byłoby już bosko (IMG:style_emoticons/default/smile.gif)

=== EDYCIA ===

Napisałem takie coś:
  1. SELECT message.* , CONCAT_WS('',a.adm_name, p.pro_name,s.stu_name) AS name,
  2. CONCAT_WS('',a.adm_surname, p.pro_surname,s.stu_surname) AS surname
  3. FROM message
  4. LEFT JOIN administrator a
  5. ON a.use_id = message.mes_from
  6. LEFT JOIN professor p
  7. ON p.use_id = message.mes_from
  8. LEFT JOIN student s
  9. ON s.use_id = message.mes_from
  10. WHERE message.mes_from = 8

Nie wydaje mi się to zbyt eleganckie, ale chyba jest skuteczne, bo otrzymałem dane, które chciałem. Teraz nie wiem czy uda mi się to przerobić na metody Zendowskie (IMG:style_emoticons/default/smile.gif) Jak się nie uda, to trzeba będzie napisać czyste zapytanie i podstawiać zmienną jako parametr.

P.S. Temat już zszedł na bok, jako MySQL.

Ten post edytował IceManSpy 28.08.2011, 22:15:36
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: 21.12.2025 - 19:49