yiiを使ってみる6

YiiFrameworkを使ってみる1h/dayシリーズ6回目。当面の目標はCRUDを自前で実装すること。今回はcreate。

CHtmlでフォームを作成する

user2 createアクション

コントローラーにcreateアクションを追加。

<?php
class User2Controller extends Controller
{
	public function actionCreate()
	{
		if ($_POST) {
			var_dump($_POST);
		}
		
		$user = new User;
		$this->render('Create',array(
			'user'=>$user,
		));
	}
}
user2 createビュー

createビューを追加する。

<h1>user2/create</h1>

<?php echo CHtml::beginForm(); ?>
 
<?php echo CHtml::activeLabel($user,'username'); ?>
<?php echo CHtml::activeTextField($user,'username'); ?>
<br>
<?php echo CHtml::activeLabel($user,'password'); ?>
<?php echo CHtml::activePasswordField($user,'password'); ?>
<br>
<?php echo CHtml::activeLabel($user,'email'); ?>
<?php echo CHtml::activeTextField($user,'email'); ?>
<br>
<?php echo CHtml::submitButton('create'); ?>
 
<?php echo CHtml::endForm(); ?>

CHtmlの各メソッドはCHtml Class Reference を参照。

確認

http://localhost/yiiprac1/index.php?r=user2/create

username/passwordになにか入力しcreateボタンをクリックすると、createページに$_POSTをvar_dumpする。

生成されたHTML(一部)

<div id="content"> 
	<h1>user2/create</h1>
	<form action="/yiiprac1/index.php?r=user2/create" method="post"> 
		<label for="User_username">Username</label>
		<input name="User[username]" id="User_username" type="text" maxlength="128" />
		<br>
		<label for="User_password">Password</label>
		<input name="User[password]" id="User_password" type="password" maxlength="128" />
		<br>
		<label for="User_email">Email</label>
		<input name="User[email]" id="User2_email" type="text" />
		<br>
		<input type="submit" name="yt0" value="create" /> 
	</form>
</div><!-- content --> 

フォームモデルを使う

yiiにはCFormModelというのがあるので使ってみる。
YiiFramework-guide-モデルの作成を参考にする。

user2フォームモデル

user2用のCFormModelを追加する。

<?php
class User2Form extends CFormModel
{
	public $username;
	public $password;
	public $email;
}
user2 createアクション

createアクションをUser2Formにあわせる。

	public function actionCreate()
	{
		if ($_POST) {
			var_dump($_POST);
		}
		
		$user = new User2Form();
		$this->render('Create',array(
			'user'=>$user,
		));
	}
確認

http://localhost/yiiprac1/index.php?r=user2/create

ポスト値は$_POST['User2Form']に入っていることがわかる。

生成されたHTML(一部)
UserがUser2Formに変わっている。

<div id="content"> 
	<h1>user2/create</h1>
	<form action="/yiiprac1/index.php?r=user2/create" method="post"> 
	<label for="User2Form_username">Username</label>
	<input name="User2Form[username]" id="User2Form_username" type="text" />
	<br>
	<label for="User2Form_password">Password</label>
	<input name="User2Form[password]" id="User2Form_password" type="password" />
	<br>
	<label for="User2Form_email">Email</label>
	<input name="User2Form[email]" id="User2Form_email" type="text" />
	<br>
	<input type="submit" name="yt0" value="create" /> 
	</form>
	<p>
	<a href="/yiiprac1/index.php?r=user2/index">index</a>
	</p>
</div><!-- content --> 

var_dump出力

array
  'User2Form' => 
    array
      'username' => string '' (length=0)
      'password' => string '' (length=0)
      'email' => string '' (length=0)
  'yt0' => string 'create' (length=6)

validator

入力値バリデーションを追加する。

user2 フォームモデル

フォームモデルrulesメソッドを追加しバリデーションルールを実装する。

<?php
class User2Form extends CFormModel
{
	public $username;
	public $password;
	public $email;

	public function rules()
	{
		return array(
			array('username, password', 'required'),
			array('email', 'email'),
		);
	}
}
user2 createアクション

$_POSTからモデルへのプロパティ設定はsetAttributesメソッドを利用する。
バリデーション結果をとりあえずvar_dumpしてみる。

	public function actionCreate()
	{
		if ($_POST['User2Form']) {
			var_dump($_POST);
			$user = new User2Form();
			$user->setAttributes($_POST['User2Form']);
			if (!$user->validate()) {
				var_dump($user->getErrors());
			}
		}
		$user = new User2Form();
		$this->render('Create',array(
			'user'=>$user,
		));
	}
確認

http://localhost/yiiprac1/index.php?r=user2/create

emailに「a」を入力して、createボタンクリックした後のvar_dump。

array
  'User2Form' => 
    array
      'username' => string '' (length=0)
      'password' => string '' (length=0)
      'email' => string 'a' (length=1)
  'yt0' => string 'create' (length=6)
array
  'username' => 
    array
      0 => string 'Username cannot be blank.' (length=25)
  'password' => 
    array
      0 => string 'Password cannot be blank.' (length=25)
  'email' => 
    array
      0 => string 'Email is not a valid email address.' (length=35)

エラー表示とDB更新をサポートする。

user2 createアクション

入力値が正常の場合、Userにsaveし、indexへリダイレクトする。
フォームモデルからActiveRecordモデルへのプロパティコピーはもっとましな方法がありそう。

	public function actionCreate()
	{
		$user = new User2Form();
		
		if ($_POST['User2Form']) {
			$user->setAttributes($_POST['User2Form']);
			if ($user->validate()) {
				$userModel = new User();
				$userModel->username = $user->username;
				$userModel->password = $user->password;
				$userModel->email = $user->email;
				if($userModel->save()) {
					$this->redirect(array('user2/index'));
				}
			}
		}
		
		$this->render('Create',array(
			'user'=>$user,
		));
	}
user2 createビュー

CHtml::errorSummary でメッセージを表示する。
indexページへのリンクを追加。

<h1>user2/create</h1>

<?php echo CHtml::beginForm(); ?>

<?php echo CHtml::errorSummary($user); ?>

<?php echo CHtml::activeLabel($user,'username'); ?>
<?php echo CHtml::activeTextField($user,'username'); ?>
<br>
<?php echo CHtml::activeLabel($user,'password'); ?>
<?php echo CHtml::activePasswordField($user,'password'); ?>
<br>
<?php echo CHtml::submitButton('create'); ?>
 
<?php echo CHtml::endForm(); ?>

<p>
<?php echo CHtml::link('index', array('user2/index')); ?>
</p>
indexビュー

createページへのリンクを追加。

<h1>user2/index</h1>

<p>
<?php echo CHtml::link('create', array('user2/create')); ?>
</p>

<ol>
<?php foreach($users as $user) : ?>
	<li>
		<?php echo $user->id; ?>&nbsp;
		<?php echo CHtml::link($user->username, array('user2/view', 'id'=>$user->id)); ?>&nbsp;
		<?php echo $user->password; ?>&nbsp;
		<?php echo $user->email; ?>&nbsp;
		<?php echo CHtml::link('delete', array('user2/delete', 'id'=>$user->id)); ?>
	</li>
<?php endforeach; ?>
</ol>
確認
  • indexページからcreateページへのリンク
  • createページでエラーになる値を入力→createボタンをクリックし、バリデーション結果が表示されること
  • createページでエラーにならない値を入力→Userテーブルに保存され、indexページが表示されること

http://localhost/yiiprac1/index.php?r=user2/index