Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Yii] Wstawienie danych do bazy - rzuca wyjątek
Forum PHP.pl > Forum > PHP > Frameworki
cod3r
Witam,

Framework na którym operuje to Yii jak widać w tytule. Problem dotyczy wstawienia danych do bazy, które są przesłane z formularza. A więc tak mam formularz register.php (widok)
  1. <h1>Registration</h1>
  2.  
  3. <?php if(Yii::app()->user->hasFlash('register')): ?>
  4.  
  5. <div class="flash-success">
  6. <?php echo Yii::app()->user->getFlash('register'); ?>
  7. </div>
  8.  
  9. <?php else: ?>
  10.  
  11.  
  12. <div class="form">
  13.  
  14. <?php $form=$this->beginWidget('CActiveForm', array(
  15. 'id'=>'register-form-register-form',
  16. 'enableAjaxValidation'=>true,
  17. )); ?>
  18.  
  19. <p class="note">Fields with <span class="required">*</span> are required.</p>
  20.  
  21. <?php echo $form->errorSummary($model); ?>
  22.  
  23. <div class="row">
  24. <?php echo $form->labelEx($model,'username'); ?>
  25. <?php echo $form->textField($model,'username'); ?>
  26. <?php echo $form->error($model,'username'); ?>
  27. </div>
  28.  
  29. <div class="row">
  30. <?php echo $form->labelEx($model,'password'); ?>
  31. <?php echo $form->textField($model,'password'); ?>
  32. <?php echo $form->error($model,'password'); ?>
  33. </div>
  34.  
  35. <div class="row">
  36. <?php echo $form->labelEx($model,'email'); ?>
  37. <?php echo $form->textField($model,'email'); ?>
  38. <?php echo $form->error($model,'email'); ?>
  39. </div>
  40.  
  41.  
  42. <div class="row buttons">
  43. <?php echo CHtml::submitButton('Submit'); ?>
  44. </div>
  45.  
  46. <?php $this->endWidget(); ?>
  47.  
  48. </div><!-- form -->
  49.  
  50. <?php endif; ?>


następnie dane przesyłane są do SiteController.php (kontrolera) w którym odbywa się walidacja
  1. <?php
  2.  
  3. class SiteController extends Controller
  4. {
  5.  
  6. //inne metody
  7. .
  8. .
  9. .
  10.  
  11. //rejestracja
  12. public function actionRegister()
  13. {
  14.  
  15. $model=new RegisterForm;
  16.  
  17. if(isset($_POST['RegisterForm']))
  18. {
  19. $model->attributes=$_POST['RegisterForm'];
  20. if($model->validate())
  21. {
  22. //wywolanie metody wykonujacej zapytanie
  23. $model->wstaw();
  24. Yii::app()->user->setFlash('register','dziekujemy za rejestracje.');
  25. $this->refresh();
  26. }
  27. }
  28. $this->render('register',array('model'=>$model));
  29. }
  30.  
  31. }


i wywoływane jest metoda wstaw z RegisterForm.php (modelu), która ma za zadanie wstawić dane do bazy.
  1. class RegisterForm extends CActiveRecord
  2. {
  3. //inne metody
  4. .
  5. .
  6. .
  7.  
  8. public function wstaw()
  9. {
  10. $connection=Yii::app()->db;
  11. $sql="INSERT INTO tbl_user (username,password,email) VALUES(:username,:password,:email)";
  12.  
  13.  
  14. $command=$connection->createCommand($sql);
  15. $command->bindParam(":username",$username,PDO::PARAM_STR);
  16. $command->bindParam(":password",$password,PDO::PARAM_STR);
  17. $command->bindParam(":email",$email,PDO::PARAM_STR);
  18. $command->execute();
  19.  
  20. }
  21. }


Niestety otrzymuję wyjątek CDbException o treści.
Cytat
CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'username' cannot be null. The SQL statement executed was: INSERT INTO tbl_user (username,password,email) VALUES(:username,:password,:email)


Nie bardzo wiem jak to ugryźć, na pierwszy rzut oka wydaje się być wszystko w porządku. Może ktoś bardziej doświadczony posłuży radą smile.gif.


EDIT:

Rozwiązałem to w inny sposób, a dokładniej za pomocą konstruktora zapytań:
  1. $command = Yii::app()->db->createCommand()
  2. ->insert('tbl_user', array(
  3. 'username'=>$this->username,
  4. 'password'=>MD5($this->password),
  5. 'email'=>$this->email,
  6. ));



Natomiast chętnie dowiem się dlaczego nie działa poprzedni kod.
artur_dziocha
$username a $this->username - może to?
viking
Ja nie widzę nigdzie we wstaw() deklaracji zmiennych które wstawiasz ($username....) stąd są null, stąd dostajesz komunikat że nie mogą być null.
cod3r
Ok, a więc faktycznie po zadeklarowaniu zmiennych
  1. $username = $this->username;
  2. $password = $this->password;
  3. $email = $this->email;

zapytanie się wykonało.

artur_dziocha sama zmiana $username na $this->$username w zapytaniu z bindowaniem też rzucała wyjątek (sprawdzałem wcześniej). Dopiero po deklaracji przeszło.

Natomiast zastanawia mnie czemu za pomocą konstruktora zapytań poszło bez deklaracji?

Kolejna śmieszna sprawa, może ktoś zna na to odpowiedź. Otóż postanowiłem sobie spróbować wykonać zapytanie właśnie za pomocą konstruktora zapytań jak i zwykłego zapytania z bindowaniem parametrów. W momencie gdy używałem jednego drugi dałem w komentarz, o tak:

  1. public function wstaw(){
  2.  
  3. $username = $this->username;
  4. $password = $this->password;
  5. $email = $this->email;
  6.  
  7. /*
  8. $command = Yii::app()->db->createCommand()
  9. ->insert('tbl_user', array(
  10.   'username'=>$this->username,
  11. 'password'=>MD5($this->password),
  12. 'email'=>$this->email,
  13. ));
  14. */
  15.  
  16.  
  17. $connection=Yii::app()->db;
  18. $sql="INSERT INTO tbl_user (username,password,email) VALUES(:username,MD5(:password),:email)";
  19.  
  20. $command=$connection->createCommand($sql);
  21. $command->bindParam(":username",$username,PDO::PARAM_STR);
  22. $command->bindParam(":password",$password,PDO::PARAM_STR);
  23. $command->bindParam(":email",$email,PDO::PARAM_STR);
  24. $command->execute();
  25.  
  26. }


I ku mojemu zaskoczeniu w bazie danych po wykonaniu rejestracji zauważyłem 2 identyczne rekordy, tak, jak by zapytanie wykonało się 2 razy. Dlaczego? Nie mam pojęcia. Natomiast jak każdą linie zakomentuję pojedynczym komentarzem (//) to dodawany jest tylko 1 rekord, czyli jest poprawnie. Ogarnia ktoś dlaczego tak się dzieje? Trochę to dziwne i zabawne tongue.gif. Wygląda to troche tak, jak by się wykonywały instrukcje zakomentowane biggrin.gif.
Spawnm
z ciekawości, czemu piszesz własna funkcję zamiast użyć istniejących $model->save/insert() ?
cod3r
Spawnm, wiem o tej funkcji z dokumentacji, natomiast piszę też projekt na uczelnię i jednym z wymogów jest by zapytania były "jawne" i implementowane przez siebie. Gdybym pisał dla siebie to pewnie, że bym użył gotowej, po co robić coś 2 razy smile.gif.
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.