Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ZF] Przerwanie skryptu po wysłaniu formularza
Forum PHP.pl > Forum > PHP > Frameworki
IceManSpy
Witam

Cały czak kontynuuję naukę Zenda i natknąłem się na fajny blog:
http://www.karolnowicki.pl/zend-framework/artykuly/
i wykonuje w nim krok po kroku wszystko z serii "Praca z bazą danych". W części pierwszej pominąłem dopisek do pliku Boostrap, ale dopisuje wszędzie przedrostek Application. Ale do rzeczy.
Model:
  1. class Application_Model_Uzytkownicy
  2. {
  3. protected $_name = 'uzytkownicy';
  4.  
  5. public function nowyUzytkownik($email, $haslo, $imie, $nazwisko, $rola, $status)
  6. {
  7. $row = $this->createRow();
  8. if ($row) {
  9. $row->email = $email;
  10. $row->haslo = $haslo;
  11. $row->imie = $imie;
  12. $row->nazwisko = $nazwisko;
  13. $row->rola = $rola;
  14. $row->status = $status;
  15. $row->save();
  16. return TRUE;
  17. } else {
  18. throw new Zend_Exception('Nie można utworzyć użytkownika. Błąd bazy danych!'); // warto tworzyć własne komunikaty o błędach, kiedy wykonujemy funkcje na tabelach
  19. }
  20. }
  21.  
  22. public function listaUzytkownikow()
  23. {
  24. $select = $this->select();
  25. $select->order('email ASC');
  26. $adapter = new Zend_Paginator_Adapter_DbTableSelect($select);
  27. return $adapter;
  28. }
  29. }

Kontrolery (ustawiłem sobie w nim echo, aby wiedzieć gdzie się wysypuje):
  1. <?php
  2.  
  3. class UzytkownicyController extends Zend_Controller_Action
  4. {
  5.  
  6. public function init()
  7. {
  8. /* Initialize action controller here */
  9. }
  10.  
  11. public function indexAction()
  12. {
  13.  
  14. }
  15. public function nowyUzytkownikAction()
  16. {
  17. $form = new Application_Form_Uzytkownik();
  18. $form->setAction('/uzytkownicy/nowy-uzytkownik')
  19. ->setMethod('post');
  20.  
  21. print_r($_POST);
  22. if($this->getRequest()->isPost()) {
  23. echo "odebrałem forma";
  24. if($form->isValid($_POST)) {
  25. echo "po walidacji";
  26. $modelUzytkownicy = new Application_Model_Uzytkownicy();
  27. $email = $form->getValue('email');
  28. $haslo = md5($form->getValue('haslo'));
  29. $imie = $form->getValue('imie');
  30. $nazwisko = $form->getValue('nazwisko');
  31. $rola = $form->getValue('rola');
  32. $status = $form->getValue('status');
  33. echo "odebrałem values";
  34. echo $email;
  35. $results = $modelUzytkownicy->nowyUzytkownik($email, $haslo, $imie, $nazwisko, $rola, $status);
  36. echo "obiekt stworzony";
  37. print_r($results);
  38. echo "po pront r";
  39. if($results) {
  40. echo "rezultat";
  41. return $this->_redirect('/uzytkownicy/lista-uzytkownikow');
  42. //$this->_helper->redirector('/uzytkownicy/lista-uzytkownikow'); // taka wersja też nie działa
  43. }
  44. }
  45. if($form->isErrors()) {
  46. $form->populate($_POST);
  47. }
  48. }
  49.  
  50. $this->view->form = $form;
  51. }
  52.  
  53. }


Formularz:
  1. class Application_Form_Uzytkownik extends Zend_Form
  2. {
  3.  
  4. public function init()
  5. {
  6. $email = $this->createElement('text', 'email');
  7. $email->setLabel('Adres e-mail:')
  8. ->setRequired(TRUE)
  9. ->setAttrib('size', 30)
  10. ->addFilters(array(
  11. new Zend_Filter_StringToLower(),
  12. new Zend_Filter_StringTrim(),
  13. new Zend_Filter_StripNewlines(),
  14. new Zend_Filter_StripTags()
  15. ))
  16. ->addValidators(array(
  17. new Zend_Validate_NotEmpty(),
  18. new Zend_Validate_EmailAddress(Zend_Validate_Hostname::ALLOW_DNS)
  19. ));
  20. $haslo = $this->createElement('password', 'haslo');
  21. $haslo->setLabel('Hasło:')
  22. ->setRequired(TRUE)
  23. ->setAttrib('size', 30)
  24. ->addFilters(array(
  25. new Zend_Filter_StringTrim(),
  26. new Zend_Filter_StripNewlines(),
  27. new Zend_Filter_StripTags()
  28. ))
  29. ->addValidators(array(
  30. new Zend_Validate_NotEmpty(),
  31. new Zend_Validate_StringLength(3, 12)
  32. ));
  33. $imie = $this->createElement('text', 'imie');
  34. $imie->setLabel('Imię:')
  35. ->setRequired(FALSE)
  36. ->setAttrib('size', 30)
  37. ->addFilters(array(
  38. new Zend_Filter_StringTrim(),
  39. new Zend_Filter_StripNewlines(),
  40. new Zend_Filter_StripTags()
  41. ))
  42. ->addValidators(array(
  43. new Zend_Validate_StringLength(2, 50)
  44. ));
  45. $nazwisko = $this->createElement('text', 'nazwisko');
  46. $nazwisko->setLabel('Nazwisko:')
  47. ->setRequired(FALSE)
  48. ->setAttrib('size', 30)
  49. ->addFilters(array(
  50. new Zend_Filter_StringTrim(),
  51. new Zend_Filter_StripNewlines(),
  52. new Zend_Filter_StripTags()
  53. ))
  54. ->addValidators(array(
  55. new Zend_Validate_StringLength(2, 50)
  56. ));
  57. $rola = $this->createElement('select', 'rola');
  58. $rola->setLabel('Rola użytkownika:')
  59. ->setRequired(TRUE)
  60. ->addFilters(array(
  61. new Zend_Filter_StringTrim(),
  62. new Zend_Filter_StripNewlines(),
  63. new Zend_Filter_StripTags()
  64. ))
  65. ->addValidators(array(
  66. new Zend_Validate_NotEmpty(),
  67. new Zend_Validate_StringLength(4, 5)
  68. ))
  69. ->addMultiOptions(array(
  70. '' => 'Wybierz rolę z listy',
  71. 'user' => 'Gość',
  72. 'autor' => 'Autor',
  73. 'admin' => 'Administrator'
  74. ));
  75. $status = $this->createElement('select', 'status');
  76. $status->setLabel('Status użytkownika:')
  77. ->setRequired(TRUE)
  78. ->addFilters(array(
  79. new Zend_Filter_StringTrim(),
  80. new Zend_Filter_StripNewlines(),
  81. new Zend_Filter_StripTags()
  82. ))
  83. ->addValidators(array(
  84. new Zend_Validate_NotEmpty(),
  85. new Zend_Validate_StringLength(1, 1)
  86. ))
  87. ->addMultiOptions(array(
  88. '' => 'Wybierz status z listy',
  89. '0' => 'Zawieszony',
  90. '1' => 'Aktywny'
  91. ));
  92. $id = $this->createElement('hidden', 'id');
  93. $this->addElements(array(
  94. $email,
  95. $haslo,
  96. $imie,
  97. $nazwisko,
  98. $rola,
  99. $status,
  100. 'submit', 'submit', array(
  101. 'label' => 'zapisz'
  102. )
  103. ),
  104. $id
  105. ));
  106. }
  107.  
  108.  
  109. }


I teraz gdy wypełnię formularz to zatrzymuje mi się na wykonaniu metody nowyUzytkownik. Wyświetla się tylko wszystko do echo "odebrałem values"; echo $email; a potem jest pusta, biała strona. Gdy błędnie wypełnię formularz, to pokazują się komunikaty o błędach i wraca do strony z formularzem. W bazie nie ma żadnych nowych rekordów. To samo się dzieje (białą, pusta strona), gdy chcę wyświetlić listę użytkowników (adres/uzytkownicy/lista-uzytkownikow).

Plik applacation.ini:
Kod
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
appnamespace = "Application"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.params.displayExceptions = 0

resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "user"
resources.db.params.password = "haslo"
resources.db.params.dbname = "naukazend2"
resources.db.params.charset = "utf8"
resources.db.isDefaultTableAdapter = true


[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1


Gdzie jest błąd? sad.gif

ROZWIĄZAŁEM:
Model ma być dziedziczony z Zend_Db_Table smile.gif
NEO.pl
Na przyszlosc: error_reporting(E_ALL) + error.log serwera Twoim przyjacielem smile.gif
KrzysiekWildfire
Łoooo, w zendzie tak nie wyświetlasz błędów, możesz sobie zmienić poniższe trzy linijki w pliku config.ini z:

phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
resources.frontController.params.displayExceptions = 0

na

phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1

Ale wtedy musisz pamiętać o tym, aby przy puszczaniu strony live przywrócić standardowe ustawienia

Powyższy model jest bleeee (oczywiście moim zdaniem)!

Dla mnie dobry model ma następujące funkcje:
toArray();
__set();
__get();
setOptions($array = null);

Dobry model wygląda tak (w zend tools: "create model User"):
  1. class Application_Model_User{
  2. protected $_email;
  3. protected $_haslo;
  4. protected $_imie;
  5. protected $_nazwisko;
  6. protected $_rola;
  7. protected $_status;
  8.  
  9. public function __construct (array $options = null)
  10. {
  11. if (is_array($options))
  12. $this->setOptions($options);
  13. }
  14. public function __set ($name, $value)
  15. {
  16. $method = 'set' . $name;
  17. if (! method_exists($this, $method))
  18. throw new Exception('Nie znaleziono metody "'.$method.'"!');
  19. $this->$method($value);
  20. return $this;
  21. }
  22. public function __get ($name)
  23. {
  24. $method = 'get' . $name;
  25. if (! method_exists($this, $method))
  26. throw new Exception('Nie znaleziono metody "'.$method.'"!');
  27. return $this->$method();
  28. }
  29. public function setOptions (array $options = null)
  30. {
  31. $methods = get_class_methods($this);
  32. foreach ($options as $key => $elem) {
  33. $method = 'set' . ucfirst($key);
  34. if (! in_array($method, $methods))
  35. throw new Exception('Nie nzaleziono metody "'.$method.'"!');
  36. $this->$method($elem);
  37. }
  38. return $this;
  39. }
  40. public function toArray(){
  41. $vars = get_class_vars(get_class($this));
  42. $array = array();
  43. foreach ($vars as $key=>$value){
  44. $method = 'get' . str_replace('_','',$key);
  45. $array[str_replace('_', '', $key)] = $this->$method();
  46. }
  47. return $array;
  48. }
  49.  
  50. public function setEmail($email){
  51. $this->_email = $email;
  52. return $this;
  53. }
  54.  
  55. public function getEmail(){
  56. return $this->_email;
  57. }
  58.  
  59. public function setHaslo($haslo){
  60. $this->_haslo = $haslo;
  61. return $this;
  62. }
  63.  
  64. public function getHaslo(){
  65. return $this->_haslo;
  66. }
  67.  
  68. public function setImie($imie){
  69. $this->_imie = $imie;
  70. return $this;
  71. }
  72.  
  73. public function getImie(){
  74. return $this->_imie;
  75. }
  76.  
  77. public function setNazwisko($nazwisko){
  78. $this->_nazwisko = $nazwisko;
  79. return $this;
  80. }
  81.  
  82. public function getNazwisko(){
  83. return $this->_nazwisko;
  84. }
  85.  
  86. public function setRola($rola){
  87. $this->_rola = $rola;
  88. return $this;
  89. }
  90.  
  91. public function getRola(){
  92. return $this->_rola;
  93. }
  94.  
  95. public function setStatus($status){
  96. $this->_status = $status;
  97. return $this;
  98. }
  99.  
  100. public function getStatus(){
  101. return $this->_status;
  102. }
  103. }


I do tego potrzebny jest jeszcze mapper (Komenda w zend_tools "create model UserMapper"):

  1. class Application_Model_UserMapper
  2. {
  3. protected $_dbTable = null;
  4. protected $_dbTableName = 'Application_Model_DbTable_User';
  5.  
  6. public function setDbTable ($dbTable)
  7. {
  8. if (is_string($dbTable))
  9. $dbTable = new $dbTable();
  10. if (! $dbTable instanceof Zend_Db_Table_Abstract)
  11. throw new Exception('Zła baza danych!');
  12. $this->_dbTable = $dbTable;
  13. }
  14. public function getDbTable ()
  15. {
  16. if (null === $this->_dbTable)
  17. $this->setDbTable($this->_dbTableName);
  18. return $this->_dbTable;
  19. }
  20. public function __construct($dbTable = null) {
  21. if ($dbTable !== null){
  22. if (is_string($dbTable)){
  23. $this->_dbTableName = $dbTable;
  24. }else{
  25. throw new Exception('Nazwa bazy danych powinna być ciągiem znaków!');
  26. }
  27. };
  28. }
  29.  
  30. public function fetchAll($select = null){
  31. $result = $this->getDbTable()->fetchAll($select);
  32. if (count($result) === 0)
  33. return null;
  34. $results = array();
  35. foreach ($result as $row){
  36. $results[] = new Application_Model_User($row->toArray());
  37. }
  38. return $results;
  39. }
  40. public function findLast($count = 5, $user = null){
  41. return $this->fetchAll($this->getDbTable()->select()->limit(5)->where('creator = ?',$user));
  42. }
  43. public function save(Application_Model_User $app){
  44. if (null === $app->getId()){
  45. $this->getDbTable()->insert($app->toArray());
  46. }else{
  47. $this->getDbTable()->update($app->toArray(), 'id = '.$app->getId());
  48. }
  49. }
  50. public function find($id){
  51. $result = $this->getDbTable()->find($id);
  52. if (count($result) === 0)
  53. return null;
  54. return new Application_Model_User($result->current()->toArray());
  55. }


potrzebujesz jeszcze bazy danych (w zend tools: "create db-table User users");

I stworzenie nowego użytkownika wygląda tak (w kontrolerze):

  1. public function nowyUzytkownikAction(){
  2. $form = new Application_Form_NewUser(); //to jest twój formularz - konieczne jest, aby pola formularza miały takie same nazwy jak nazwy zmiennych w modelu
  3. if ($this->_request->isPost()){
  4. if ($form->isValid($this->_request->getPost())){
  5. $user = new Application_Model_User($form->toArray());
  6. $user->haslo = md5($user->haslo);
  7. $userMapper = new Application_Model_UserMapper();
  8. $userMapper->save($user);
  9. $this->_redirect('/sciezka/do/przeniesienia/uzytkownika');
  10. }
  11. }
  12. }


I powinno wszystko elegancko śmigać.
Pilsener
A po co taki kombajn? Przecież to wszystko jest gotowe w Zend_Db_Table
Wystarczy prosty model:
  1. class Model_Users extends Zend_Db_Table_Abstract{
  2.  
  3. protected $_name = 'users';
  4.  
  5. public function getById ($id) {
  6. $select = $this->select();
  7. $select->where('id = ?', $id);
  8. return $this->fetchRow($select);
  9. }
  10. }

Wykorzystanie:
  1. //pobieranie danych
  2. $model = new Model_Users();
  3. $user = $model->getById(12);
  4. echo $user->nick;
  5.  
  6. //dodanie nowego usera
  7. $data = array(
  8. 'email'=>$email,
  9. 'nick'=>$nick
  10. );
  11. $model->insert($data);


KrzysiekWildfire
Jestem już tak przyzwyczajony - tym bardziej, że nie piszę małych projektów a tworząc tak mam wszystko na swoim miejscu - i można w takiej klasie tworzyć metody do zarządzania danymi. Potworzyłem sobie klasy w których mam te najczęściej wykorzystywane funkcje (__get, __set, itd) i stworzyłem sobie generator - Czysto, i wszystko z łatwością mogę stworzyć w kilka chwil.
cudny
Cytat(Speedy @ 9.04.2011, 14:45:39 ) *
Nie wiem, czy prościej, bo do wykonania tak banalnej czynności jest załączany zewnętrzny plik i jakaś klasa. Moje rozwiązanie mieści się w 1 linijce i robi to samo.



Cytat(Pilsener @ 16.04.2011, 21:40:11 ) *
A po co taki kombajn? Przecież to wszystko jest gotowe w Zend_Db_Table
Wystarczy prosty model:
  1. class Model_Users extends Zend_Db_Table_Abstract{
  2.  
  3. protected $_name = 'users';
  4.  
  5. public function getById ($id) {
  6. $select = $this->select();
  7. $select->where('id = ?', $id);
  8. return $this->fetchRow($select);
  9. }
  10. }

Wykorzystanie:
  1. //pobieranie danych
  2. $model = new Model_Users();
  3. $user = $model->getById(12);
  4. echo $user->nick;
  5.  
  6. //dodanie nowego usera
  7. $data = array(
  8. 'email'=>$email,
  9. 'nick'=>$nick
  10. );
  11. $model->insert($data);



Eee no,

jak ma być prosto to raczej tak:
  1. // pobieranie
  2. $result = $model->find($id)->current();
  3. // a co do tworzenia tablicy do pamieci to lepiej utrworzyc ja jednak do wymazania przez sama metode czyli
  4. $model->insert(array('email' => $email, 'nick' => $nick));


biggrin.gif
KrzysiekWildfire
wykorzystanie mojego modelu wygląda tak:

  1. $model = new Application_Model_UserMapper();
  2. $user = $model->find($id); //znalezienie 1 użytkownika
  3. $users = $model->fetchAll(); //znalezienie wszystkich
  4.  
  5. //modyfikacja użytkownika:
  6. $user->setMail($mail);
  7. $model->save($user);
  8.  
  9. //jeżeli potrzeba wyciągnąć dane:
  10. user->toArray();


No a poza tym, jeżeli tak wyciągniesz te dane, np do kontrolera - to chyba nie manipulujesz w nim tymi danymi - Powstaje potężny zgrzyt - kontroler nie służy do manipulowania danymi - funkcje pisze się w modelach.
MVC
cudny
Cytat(KrzysiekWildfire @ 19.04.2011, 14:16:19 ) *
No a poza tym, jeżeli tak wyciągniesz te dane, np do kontrolera - to chyba nie manipulujesz w nim tymi danymi - Powstaje potężny zgrzyt - kontroler nie służy do manipulowania danymi - funkcje pisze się w modelach.
MVC


W modelach operujesz na danych z bazy, zapisywaniu ew. szybkim przetwarzaniu - resztę robisz w kontrolerach, ja używam do tego jeszcze pisanych przeze mnie bibliotek ale całość i tak trzeba wypluć do widoku z kontrolera wiec... nie rozumiem jak przetwarzasz to wszystko w modelu.
Ogólnie tworzę sobie w library obok Zend katalog powiedzmy Project i w nim daje funkcje związane powiedzmy z XML czy przetwarzanie danych czy jakieś stałe walidacje formularzy, które często wykorzystuje.
Nie wyobrażam sobie tego mieszać z zapytaniami do bazy - model jest tylko do użytku od strony biznesowej kodu, a nie do umieszczania w nim jakiś modułów.
Bardzo często robię rozbudowane zapytania w pracy i nie wiem jak można do klas modeli wstawiać jakieś inne metody wykorzystywane w kontrolerze ?
Przecież w modelu dziedziczysz sporo danych z innych klas i co - jeśli chce sobie napisać funkcję powiedzmy, no nie wiem... between:
  1. public function between($from, $to, $value) {
  2. if($value > $to || $value < $from) return false;
  3. return true;
  4. }


I co - walne to do modelu ?
Chyba inaczej rozumiemy MVC biggrin.gif
KrzysiekWildfire
Może inaczej:
Zend Framework: Documentation
Zapraszam do lektury bo ciekawa.
cudny
Ooo, super książka, skąd masz taką biggrin.gif

Niestety tak jak napisałem, wszytkie opisane w niej metody dotyczą jedynie danych związanych z modelem czyli... wow smile.gif dane do walidacji w tym przypadku biggrin.gif
Niemniej jednak jeśli musisz zrobić walidację, której zend nie posiada to co zrobisz ? wrzucisz do modelu jako metoda i ... kurcze - cały model będziesz musiał wywołać żeby tej metody użyć innym modelu ?
Model jest tylko do obróbki danych używanych do insetów, selectów i updatów. Po seleccie z bazy danych obrabiasz to już w controlerach i własnych klasach !

Acha - żeby nie było - odwołuję się tutaj do twoich słów:
Cytat
Powstaje potężny zgrzyt - kontroler nie służy do manipulowania danymi - funkcje pisze się w modelach.

A jeśli chodzi o __get __set to jak najbardziej używać należy ale... funkcji nie pisze się w modelach
cudny
Cytat(kalipek @ 21.04.2011, 23:40:53 ) *


Wszystkie moje posty w tym temacie to bzdura.
Ogólnie cieszę się tylko, że większość aplikacji i tak pisałem na osobnych modułach tworząc własną bibliotekę (
Cytat
taaa, obrabiaj sobie w kontrolerze, obrabiaj
- nic nie obrabiałem w kontrolerze tongue.gif) więc nie będę miał kłopotów z przerobieniem obecnie pisanych aplikacji. Niestety przychodzi też taki czas, że trzeba się przyznać do błędu i opuścić głowę biggrin.gif
Oczywiście pojmując (błędnie) MVC poszedłem na skróty i uczyłem się od kolegów z pracy którzy... chyba zrobili tak jak ja smile.gif
Ten błąd pojmowania MVC jest dokładnie opisany w podanym przez kalipka linku smile.gif (tym drugim)
Od 2 lat żyłem z klapkami na oczach, a wystarczyło jednak samemu troszki się pouczyć biggrin.gif

Artykuł: http://blog.astrumfutura.com/2008/12/the-m...-unappreciated/ otworzył mi oczy smile.gif
KrzysiekWildfire
Ja też z początku miałem ZŁE podejście do M. Wiadomo, nie od razu Rzym zbudowano. Życzę powodzonka przy przyszłych projektach.
Apo
Cytat(KrzysiekWildfire @ 14.04.2011, 20:15:20 ) *
public function fetchAll($select = null){
$result = $this->getDbTable()->fetchAll($select);
if (count($result) === 0)
return null;
$results = array();
foreach ($result as $row){
$results[] = new Application_Model_User($row->toArray());
}
return $results;
}


Mam pytanie @KrzysiekWildfire.
Jak rozwiązałeś opakowanie zwracanych danych w metodzie fetchAll, gdy używasz klasy Zend_Paginator?
Próbowałem robić:
  1. <?php
  2. foreach ($result as $row) {
  3. $entries[] = new Application_Model_Product(
  4. $result instanceof Zend_Paginator ? $row : $row->toArray());
  5. ?>

Niestety po zwróceniu wyników w widoku nie mogę wygenerować paginatora, ponieważ zwracane wyniki nie
są instancją klasy Zend_Paginator.

// edycja
Już rozwiązałem problem. Należy stworzyć filtr:
Kod
$paginator>setFilter(new Zend_Filter_Callback(array($this, 'getProductObjects')));

następnie tworzymy metodę:
Kod
<?php
public function getProductObjects($result)
    {
        $entries = array();
        foreach($result as $row) {
            $entries[]  = new Application_Model_Product($row instanceof Zend_Db_Table_Row
                              ? $row->toArray(): $row);
        }
        return $entries;
    }
?>
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.