Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [CI] MVC
Forum PHP.pl > Forum > PHP > Frameworki
Exodus
Zacząłem swoją przygodę z CI. Czy dobrze myślę?

  1. <?php
  2. class Index extends Controller
  3. {
  4.  
  5. /*
  6. Konstruktor
  7. */
  8.  
  9. function __construct()
  10. {
  11.  parent::Controller();
  12.  
  13.  $this->load->model('New_items'); 
  14. }
  15.  
  16. /*
  17. Strona glowna
  18. */
  19.  
  20. function index()
  21. {
  22.  
  23. $this->response['new_movies'] = _getNewMovies();
  24.  
  25. $this->load->view('index', $this->response);
  26. }
  27.  
  28. }
  29.  
  30. /*
  31. Najnowsze filmiki
  32. */
  33.  
  34. function _getNewMovies()
  35. {
  36.  
  37. $query = $this->get_new_movies('4');
  38.  
  39.  
  40.  
  41.  
  42. }
  43. ?>


chodzi mi o te funkcje _getNewMovies.

Np mam pobrac z bazy 3, najnowsze filmy, 4 cytaty itp. Czy dobrym pomyslem jest robienie nowych funkcji nie widocznych dla URL'a?
Diwi
Ja bym to zrobił tak:

  1. <?php
  2.  
  3. function index()
  4. {
  5.  
  6. $this->response['new_movies'] = $this->db->get('movies', '0', '4');
  7.  
  8. $this->load->view('index', $this->response);
  9. }
  10.  
  11. ?>


winksmiley.jpg

Polecam poczytać User Guide: http://codeigniter.com/user_guide/database...ive_record.html
Que
DIWI
Ale wtedy to jest MVC bez M (Modelu) tongue.gif
Exodus
No dobrze, ale dlaczego całą stroną powinien zarządzać 1 kontroller a nie każdą podstroną 1 kontroller?
grzesiek_g
Dlaczego od razu jeden kontroler? Nie widzę sensu robienia funkcji takich jak Twoja niedostępnych z poziomu URL, a to z tego powodu, że zwyczajem w CI jest dodawanie na początku pliku:
Kod
if (!defined('BASEPATH')) exit('No direct script access allowed');
.
To rozwiązuje problemy z bezpośrednim dostępem do funkcji przez kogoś kto chce ją wywołać bezpośrednio.
Ja bym to tak napisał:
  1. <?php
  2. function index() {
  3. $this->response['new_movies'] = $this->Film_Model->getNewMovies();
  4.  
  5. $this->load->view('index', $this->response);
  6. }
  7. ?>

i później odpowiednia funkcja w modelu Film_Model, który załadujesz albo w konstruktorze albo w funkcji index().
Polecam stronę http://code-igniter.pl - może nie ma jeszcze wielu postów, ale te z odnośniami do tutoriali po polsku są.
Exodus
Ale ja zadałem pytanie dlaczego każda podstrona nie powinna mieć swojego kontrollera. I kiedy tworzyć nowy kontroller? Gdzie foreach'owac wyniki z bazy?

Btw. Dobrze mam napisana funkcje w modelu?

  1. <?php
  2. function getNewMovies($how){
  3.  
  4. $this->db->limit(0,$how);
  5. $this->db->orderby('add_date', 'ASC');
  6.  
  7. return $this->db->get('video');
  8.  
  9. }
  10. ?>
grzesiek_g
Dajmy taki przykładowy kontroler newsy, tutaj nie ma sensu pisać wielu funkcji, więc jeden kontroller - jedna podstrona. Inny przykład w newsy w panelu, możemy tutaj obsługiwać kilka podstron, a posłużą do tego funkcje w kontrolerze, m.in. dodaj, edytuj, usuń, zablokuj...

Jeśli chodzi o wyrzucenie wyników z bazy jeśli mam wyswietlić bezpośrednio do widoku to nie bawię się w kontrolerze, gdy korzystam z szablonu dedykowanego dla jednego rekordu wtedy przypisuję w kontrolerze dane do widoku pojedyńczo w pętli, a następnie tablicę utworzoną z takich szablonów ładuję do widoku który jest nadrzędny.
Np.
  1. <?php
  2. $strony = Realizacje_Model::getDataPublished($this->config->item('ilosc_stron_glowna'), $site_num)->result();
  3.  
  4. $this->strony['content'] = '';
  5.  
  6. foreach($strony as $row) {
  7. $this->strony['content'] .= $this->load->view('glowna/strona', array('row' => $row), TRUE); // jest to widok pokazujący cząstkę strony, która jest powtarzalna
  8. }
  9.  
  10. $this->response['content'] = $this->load->view('glowna/portfolio', $this->strony, TRUE);
  11.  
  12. $this->load->view('index', $this->response);
  13. ?>


-- EDIT --
Co do funkcji to jest ok, ale można by dodać jeszcze warunek jeśli zapytanie nie zwróci wyników.
Exodus
Severity: Notice

Message: Undefined variable: row

Filename: views/index.php

Line Number: 4





  1. <?php
  2. $this->response['new_movies'] = $this->New_items->getNewMovies('4');
  3.  
  4. $query = $this->response['new_movies'] -> result();
  5.  
  6. foreach($query as $row) {
  7. $this->response['content'] .= $this->load->view('index', array('row' => $row), TRUE); // jest to widok pokazujący cząstkę strony, która jest powtarzalna
  8. }
  9. ?>





Wyczytałem żeby nie foreachować wyników w kontrollerze. Kiepsko coś tłumaczysz, bo nie mogę zrozumieć kiedy mam tworzyc nowy kontroller, a kiedy operować na 1
nrm
Cytat(Exodus @ 8.11.2007, 21:42:01 ) *
Zacząłem swoją przygodę z CI. Czy dobrze myślę?

Dobrze.

Cytat(Exodus @ 8.11.2007, 21:42:01 ) *
Czy dobrym pomyslem jest robienie nowych funkcji nie widocznych dla URL'a?

Zależy od sytuacji ale ogólnie bardzo dobrym.

Cytat(Diwi @ 8.11.2007, 22:45:18 ) *
Ja bym to zrobił tak:

Nie propaguj złych nawyków winksmiley.jpg

Cytat(Exodus @ 9.11.2007, 07:15:41 ) *
No dobrze, ale dlaczego całą stroną powinien zarządzać 1 kontroller a nie każdą podstroną 1 kontroller?

A po co? 1 podstrona=1 kontroler? ile byś tego miał? w tym żadnego sensu nie ma.

Cytat(Exodus @ 9.11.2007, 12:52:51 ) *
I kiedy tworzyć nowy kontroller? Gdzie foreach'owac wyniki z bazy?
Btw. Dobrze mam napisana funkcje w modelu?

Wtedy kiedy logika mówi, że potrzebujesz nowy.
Wyniki przetwarzasz w widoku.
Dobrze.
Exodus
Kiepsko mi się trochę widzi. Wkońcu Widok jest żeby "oduzależnić" PHP od strony wizualnej. Mówisz, że najlepszą opcją jest używanie "forecza" w widoku ?

Cytat
A po co? 1 podstrona=1 kontroler? ile byś tego miał? w tym żadnego sensu nie ma.


A jaki sens jest, żeby PHP parsowało za każdym razem te podstrony do których tak naprawdę nie wchodzisz. Wchodzisz na strone główną a parsuje wszystkie podstrony. Czy nie wydaje Ci się, że to jest Non-Sens?
grzesiek_g
Co do bezsensu 1 kontroler = 1 podstrona mogę się częściowo zgodzić, np gdy piszemy panel, tam możemy ładnie pogrupować sobie metody w klasach (kontrolerach), gdy piszemy dużą stronę to jeśli w innym wypadku pogrupujemy w kontrolerach różne podstrony musimy korzystać z routera. Poza tym to trochę nam zaciemni kod, przynajmniej tak mi się wydaje.

OK, wytłumaczę jak ja to widzę dokładniej:
Mamy taką niewielką stronę:
- newsy pogrupowane w kategorie,
- formularz kontaktowy,
- strona o nas,

Chcemy uzyskać taką strukturę linków:
http://example.org/news/12/ruszyla-nowa-strona
http://example.org/newsy/1
http://example.org/kategoria/1/nowosci
http://example.org/kontakt ...

1. Piszemy kontroler dla kategorii newsów w panelu z metodami: index (lista), dodaj, edytuj, usun.
dostaniemy np taki adres: http://example.org/kategorie_admin/edytuj/123
2. Podobny kontroler dla zarządzania newsami.
3. Na głównej wyświetlamy newsy - kontroler np Newsy
4. Rozwinięcie newsa - kontroler News (można też dać oddzielną metodę w kontrolerze Newsy, ale wtedy albo nam się wydłuży url, albo będziemy musieli utworzyć regułę dla routera)
5. Kontroler dla formularza kontaktowego
6. Kontroler dla pozostałych stron statycznych i tu podobnie, albo dłuższy url, albo router (można też rozbić to na oddzielne kontrolery)

Wszystko moim zdaniem zależy od tego ile przewidujemy kontrolerów, jeśli mała stronka to można spokojnie pisać na wielu kontrolerach, ale w pewnym momencie, wraz ze wzrostem liczby kontrolerów bardziej sensownym rozwiązaniem będzie tak jak pisze normanos, grupowanie.

Parsowana jest jedynie metoda którą wywołujesz, więc nic nie stoi na przeszkodzie by kilka metod umieścić w jednym kontrolerze.

Jeśli chodzi o foreach-owanie danych z bazy w kontrolerze to jest to dyskusyjna sprawa, robię tak by widok był mniej skomplikowany, ale tylko jeśli mam szablon który powtarzam wielokrotnie.
nrm
Masz zupełnie złe podejście w obu sprawach:

ad. 1 - kontroler jest od sterowania przebiegiem, widok jest oddzielony od aplikacji. Gdzie chcesz pomielić dane z htmlem? w modelu, kontrolerze? To podstawowy błąd osób początkujących,myślą, że jak oddzielenie to nie może być tam ani grama php winksmiley.jpg

ad.2 ale co Ci się znowu parsuje skoro masz wywoływane odpowiednie metody a nie wszystkie?!? Tak, wydaje mi się, że tok Twojego myślenia jest nonsensowny winksmiley.jpg

Cytat(grzesiek_g @ 9.11.2007, 16:05:28 ) *
5. Kontroler dla formularza kontaktowego
6. Kontroler dla pozostałych stron statycznych i tu podobnie, albo dłuższy url, albo router (można też rozbić to na oddzielne kontrolery)

Tu się z Tobą nie zgodzę. Po co tyle kontrolerów? Kontroler dla formularza? WTF?!? Wystarczy jedna metoda. Linki sobie ustawisz w routerze wg.własnego widzimisię.

Kontrolery powinniście tworzyć wg.klucza logicznego: obsługa newsów, artykułów, userów, itd. i nie sugerować się urlem tylko logiką.
grzesiek_g
Cytat(normanos @ 9.11.2007, 16:09:34 ) *
ad. 1 - kontroler jest od sterowania przebiegiem, widok jest oddzielony od aplikacji. Gdzie chcesz pomielić dane z htmlem? w modelu, kontrolerze? To podstawowy błąd osób początkujących,myślą, że jak oddzielenie to nie może być tam ani grama php winksmiley.jpg

Ale ja nie neguję użycia php w widoku, wyraźnie napisałem, że ładuję do widoku dane z bazy danych - przekazane od kontrolera bez żadnej jego obróbki. Ale jeśli mam szablony wielokrotne to najpierw ładuję w foreach dane do szablonów, a dopiero później wysyłam to do widoku. Ale to tylko w tym wypadku, poza tym nie widzę nic złego w umieszczeniu w kontrolerze odwołania do funkcji która mi obcina z danych odpowiednią ilość znaków, wyświetla datę...

Cytat(normanos @ 9.11.2007, 16:09:34 ) *
ad.2 ale co Ci się znowu parsuje skoro masz wywoływane odpowiednie metody a nie wszystkie?!? Tak, wydaje mi się, że tok Twojego myślenia jest nonsensowny winksmiley.jpg

Nie wiem czy to akurat do mnie, bo to była odpowiedź na wcześniejszy post Exodusa.

Cytat(normanos @ 9.11.2007, 16:09:34 ) *
Tu się z Tobą nie zgodzę. Po co tyle kontrolerów? Kontroler dla formularza? WTF?!? Wystarczy jedna metoda. Linki sobie ustawisz w routerze wg.własnego widzimisię.

Nie napisałem, że tak ma być - CI jest tak elastyczny, że daje nam swobodę wyboru i jaką ktoś drogę obierze - taka będzie dobra, co nie znaczy, że najlepsza... Ja osobiście wolę rozbicie jeśli nie mam wielu plików, wtedy mam wszystko uporządkowane. Używania routera nie neguję, tak jak napisałem - jak wygodniej.
Exodus
Zacząłem już trochę robić smile.gif.

Czy ten model jest napisany, dobrze i optymalnie ?

  1. <?php
  2. class New_items extends Model
  3. {
  4.  
  5. /*
  6. Konstruktor
  7. */
  8.  
  9. function __construct(){
  10.  
  11. parent::Model();
  12. $this->load->database();
  13.  
  14. }
  15.  
  16. /*
  17. Najnowsze filmiki
  18. */
  19.  
  20. function getNewMovies($how){
  21.  
  22. $this->db->limit($how,0);
  23. $this->db->orderby('add_date', 'DESC');
  24. $this->db->where('accepted', '1'); 
  25.  
  26. return $this->db->get('video');
  27.  
  28. }
  29.  
  30. /*
  31. Najnowsze gry On-Line
  32. */
  33.  
  34. function getNewGames($how){
  35.  
  36. $this->db->limit($how,0);
  37. $this->db->orderby('add_date', 'DESC');
  38. $this->db->where('accepted', '1'); 
  39.  
  40. return $this->db->get('games');
  41.  
  42. }
  43.  
  44. /*
  45. Najnowsze zdjęcia z galerii
  46. */
  47.  
  48. function getNewPictures($how){
  49.  
  50. $this->db->limit($how,0);
  51. $this->db->orderby('add_date', 'DESC');
  52. $this->db->where('accepted', '1'); 
  53.  
  54. return $this->db->get('gallery');
  55.  
  56. }
  57.  
  58. /*
  59. Najnowszy cytat
  60. */
  61.  
  62. function getNewCytat(){
  63.  
  64. $this->db->limit(1,0);
  65. $this->db->orderby('name',RAND());
  66. $this->db->where('accepted', '1'); 
  67.  
  68. return $this->db->get('cytaty');
  69.  
  70. }
  71.  
  72. /*
  73. Banner prawa strona
  74. */
  75.  
  76. function getReklama(){
  77.  
  78. $this->db->limit(1,0);
  79. $this->db->orderby('id',RAND());
  80. $this->db->where('page', 'index'); 
  81.  
  82. return $this->db->get('banners');
  83.  
  84. }
  85.  
  86. /*
  87. Najaktywniejsi użytkownicy
  88. */
  89.  
  90. function getMostActiveUsers($how){
  91.  
  92. $this->db->limit($how,0);
  93. $this->db->orderby('points','DESC');
  94.  
  95. return $this->db->get('users');
  96.  
  97. }
  98.  
  99. /*
  100. Najnowsi użytkownicy
  101. */
  102.  
  103. function getNewUsers($how){
  104.  
  105. $this->db->limit($how,0);
  106. $this->db->orderby('register_date','DESC');
  107. $this->db->where('activation', '0')  
  108.  
  109. return $this->db->get('users');
  110.  
  111. }
  112.  
  113.  
  114. }
  115. ?>
grzesiek_g
Cytat(Exodus @ 9.11.2007, 16:49:15 ) *
function getNewUsers($how){

$this->db->limit($how,0);
$this->db->orderby('register_date','DESC');
$this->db->where('activation', '0')

return $this->db->get('users');

}

Można też tak:
  1. <?php
  2. function getNewUsers($how){
  3.  
  4. $this->db->limit($how,0);
  5. $this->db->orderby('register_date','DESC');
  6. $this->db->where('activation', '0')  
  7.  
  8. if ($res = $this->db->get('users')->result()) 
  9. return $res;
  10. else
  11. return FALSE;
  12. }
  13. ?>

Od razu mamy pobrany w modelu wynik zapytania poprzez funkcje result(), oraz sprawdzamy czy zapytanie się wykonało.

Ale może normanos jeszcze się wypowie na ten temat.
Exodus
No i teraz znowu mam pytanie.

Załóżmy chcę zrobić podgląd profilu danego użytkownika. To mam stworzyć nowy kontroler np. profile, dać w nim funkcje index() zwracającą listę wszystkich użytkowników, look(); tam będzie pobierane id usera i na podstawie jego wyświetlany profil, czy robić to w tym samym kontrolerze co zrobiłem dotychczas czyt. Index.
nrm
Cytat(grzesiek_g @ 9.11.2007, 16:42:41 ) *
poza tym nie widzę nic złego w umieszczeniu w kontrolerze odwołania do funkcji która mi obcina z danych odpowiednią ilość znaków, wyświetla datę...

No, a ja właśnie widzę winksmiley.jpg

Wyobraź sobie np.metody /feed/atom i /feed/rss kontrolera feed (po prawdzie to jedną metodę). Z modelu pobierasz dane i przekazujesz je do widoku (wczytujesz wersje rss/atom). Gdybyś teraz chciał się bawić tymi helperami poza widokiem to musiałbyś robić osobne ścieżki dojścia do tych widoków. Tylko niepotrzebne kombinacje. Co więcej, robiąc zmiany, dodając coś, masz już kontroler strasznie ukierunkowany na daną czynność (lub model) i wtedy pod znakiem zapytania staje wykorzystanie danej metody w innym celu. A jak starasz się to zrobić bardziej ogólnie to wtedy problemem staje się tylko wczytanie odpowiedniego widoku a nie pisanie kolejnych metod.

Pamiętaj KISS (tudzież BUZI) smile.gif no i DRY

Cytat(grzesiek_g @ 9.11.2007, 16:42:41 ) *
Od razu mamy pobrany w modelu wynik zapytania poprzez funkcje result(), oraz sprawdzamy czy zapytanie się wykonało.
Ale może normanos jeszcze się wypowie na ten temat.

Słusznie, można to robić np. tak:

  1. <?php
  2. if($sql->num_rows() > 0)  
  3. {
  4. return $sql->result();  
  5.  
  6. }
  7. return FALSE;
  8. ?>


Cytat(Exodus @ 9.11.2007, 17:10:57 ) *
Załóżmy chcę zrobić podgląd profilu danego użytkownika. To mam stworzyć nowy kontroler np. profile, dać w nim funkcje index() zwracającą listę wszystkich użytkowników, look(); tam będzie pobierane id usera i na podstawie jego wyświetlany profil, czy robić to w tym samym kontrolerze co zrobiłem dotychczas czyt. Index.

Na logikę: osobny kontroler. U mnie profil to blisko 40 różnych funkcji więc logicznym było wydzielenie tego.
Exodus
A chciałbym wiedzieć jeszcze jedną kwestię. Jak to zrobić? Bo mam w tej chwili szablon pocięty na 3 części:

-Header
--XXX
-Footer

W tej chwili header nie ma żadnego kontrollera, jest tylko luźnym widokiem. To samo footer. Ale jak przyjdzie robić w headerze że jeżeli użytkownik jest zalogowany to nie wyświetla okna logowania, tylko linki typu. >Witaj xxx, Edytuj profil itp.

Jak to zrobic żeby nie pisać w każdym kontrollerze funkcji sprawdzającej czy użytkownik jest zalogowany ?
grzesiek_g
Ja bym stworzył nowy kontroler, który obsługuje profile i w oddzielnych metodach lista, profil użytkownika, pliki użytkownika, czy co tylko nam potrzeba...

Cytat
Jak to zrobic żeby nie pisać w każdym kontrollerze funkcji sprawdzającej czy użytkownik jest zalogowany ?

Piszesz klasę do obsługi autoryzacji i autentykacji, ładujesz ją w konstruktorze i wywołujesz tylko metodę z tej klasy.

Cytat
W tej chwili header nie ma żadnego kontrollera, jest tylko luźnym widokiem.

Jak chcesz zrobić kontroler dla nagłówka? Nie w tą stronę idziesz. Ja w kontrolerze w metodzie, w zależności od potrzeb wysyłam różne dane do nagłówka, np. tytuł strony, wywołanie pliku javascript... Ale jest to kontroler odpowiedzialny za treść strony, np newsy. Wspólne dane dla różnych metod tego samego kontrolera możemy wstępnie ustawić w konstruktorze.
Exodus
Ale gdzie tą klasę piszę... Gdzie ją umieszczam ...
nrm
$this->load->view('costam',#data);

a w costam:
<?php $this->load->view('header');?>
twoja tresc
<?php $this->load->view('footer');?>

choć osobiście korzystam z zupełnie innej biblioteki widoku, która jest wygoniejsza w użyciu.Postaram się to opisać z akilka dni na blogu.
Exodus
To może powiedziałbyś mi skąd pobrać tą bilbiotekę (tylko dokładny link), byłbym wdzięczny. Póki nie jest jeszcze za późno;)
grzesiek_g
Zdaje się, że coś takiego było w http://www.php.rk.edu.pl/w/p/kurs-ci/, kolejny link na wiki codeignitera: http://codeigniter.com/wiki/Category:Libra...:Authorization/. Na podstawie tego na pewno, albo coś sobie wybierzesz, albo napiszesz coś swojego. Co do FreakAuth to podobno jest trochę przeładowana biblioteka, ale nie wiem tego z własnego doświadczenia.
Poza tym tutaj http://www.code-igniter.pl/index.php/board,3.0.html znajdziesz jeszcze parę odnośników do zasobów.
Exodus
Hmm... Cos sie popsulo chyba, bo link widzi jako folder tzw. Zapętlowany mod_rewrite

jestem w index

wchodze w jakas podstrone jest index/index/podstrona
wchodze jeszcze raz i jest index/index/index/podstrona
nrm
ale o czym ty mówisz? smile.gif Jak nie będziesz dokładny to nie licz, że ktoś szklana kulą wyczaruje rozwiązanie winksmiley.jpg
Exodus
Zapomnialem o site_url smile.gif Juz wszystko ok. Mam pytanie jeszcze jak to najlepiej zrobic. Musze zrobic cos takiego:

Chcę zrobić trzyetapową rejestrację a mianowicie

1 etap - Akceptacja regulaminu
2 etap - Formularz rejestracyjny
3 etap - strona z błędami

Jak to najlepiej zrobić.

Mam robić 2 funkcje register i register_accepted i 3 widoki register, register_accepted, register_errors ?

Jak jeszcze zrobić, no bo nie ma sensu chyba w każdym kontrollerze pisać funkcji obliczajacej średnią arytmetyczną. Gdzie napisać taką funkcję, w jakim folderze umieścić jak załadowac i jak na niej operować?

Mógłby mi ktoś pomóc?
grzesiek_g
Jeden kontroler, trzy widoki.

Funkcje wspólne umieszczasz w klasie w folderze system/application/libraries, przykład:
  1. <?php
  2. if (!defined('BASEPATH')) exit('No direct script access allowed');
  3. class Site {
  4. function example() {
  5. // nasza funkcja
  6. }
  7. }
  8. ?>

Następnie ładujemy bibliotekę:
  1. <?php
  2. $this->load->Library('Site');
  3. ?>

i w kodzie:
  1. <?php
  2. $zmienna = Site::example();
  3. ?>
Exodus
Grzesiek jak mozesz podaj mi na PW swoje gg smile.gif

Jeszcze takie zasadnicze pytanie:

Strona ma wyglądać tak

Strona główna
-Filmy
-Cytaty
-Opisy gg
-Reszta

I najlepszy sposobem bedzie zrobienie tak:

Pierwszy kontroller - Index (funkcja tylko jedna- index) - Domyslny
Drugi kontroller - Movies (funkcje index - kategorie z filmami jakies tam info, movie - lista filmow ktore naleza do danej kategorii, video - film)
Trzeci kontroller Cytaty (ala movies)
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.