start-forms.md 12.7 KB
Newer Older
1 2 3
フォームを扱う
==============

4
この節では、ユーザからデータを取得するためのフォームを持つ新しいページを作る方法を説明します。
5
このページは名前のインプットフィールドとメールのインプットフィールドを持つフォームを表示します。
6
ユーザからこれら二つの情報を受け取った後、ページは入力された値を確認のためにエコーバックします。
7

8
この目的を達するために、一つの [アクション](structure-controllers.md) と 二つの [ビュー](structure-views.md) を作成する以外に、一つの [モデル](structure-models.md) をも作成します。
9

10
このチュートリアルを通じて、次の方法を学びます。
11

12 13 14
* フォームを通じてユーザによって入力されるデータを表す [モデル](structure-models.md) を作成する方法
* 入力されたデータを検証する規則を宣言する方法
* [ビュー](structure-views.md) の中で HTML フォームを構築する方法
15 16


17
モデルを作成する <span id="creating-model"></span>
18 19
----------------

20
ユーザに入力してもらうデータは、下に示されているように `EntryForm` モデルクラスとして表現され、`models/EntryForm.php` というファイルに保存されます。
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
クラスファイルの命名規約についての詳細は [クラスのオートロード](concept-autoloading.md) の節を参照してください。

```php
<?php

namespace app\models;

use yii\base\Model;

class EntryForm extends Model
{
    public $name;
    public $email;

    public function rules()
    {
        return [
            [['name', 'email'], 'required'],
            ['email', 'email'],
        ];
    }
}
```

このクラスは、Yii によって提供される基底クラス [[yii\base\Model]] を拡張するものです。
通常、この基底クラスがフォームデータを表現するのに使われます。

> Info|情報: [[yii\base\Model]] はデータベーステーブルと関連*しない*モデルクラスの親として使われます。
データベーステーブルと対応するモデルクラスでは、通常は [[yii\db\ActiveRecord]] が親になります。

51
`EntryForm` クラスは二つのパブリックメンバー、`name``email` を持っており、これらがユーザによって入力されるデータを保管するのに使われます。
52
このクラスはまた `rules()` という名前のメソッドを持っています。このメソッドがデータを検証する一連の規則を返します。
53
上記で宣言されている検証規則は次のことを述べています。
54 55 56 57

* `name``email` は、ともに値を要求される
* `email` のデータは構文的に正当なメールアドレスでなければならない

58 59
ユーザによって入力されたデータを `EntryForm` オブジェクトに投入した後、[[yii\base\Model::validate()|validate()]] を呼んでデータ検証ルーチンを始動することが出来ます。
データ検証が失敗すると [[yii\base\Model::hasErrors|hasErrors]] プロパティが true に設定されます。
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
そして、[[yii\base\Model::getErrors|errors]] を通じて、どのような検証エラーが発生したかを知ることが出来ます。


```php
<?php
$model = new EntryForm();
$model->name = 'Qiang';
$model->email = 'bad';
if ($model->validate()) {
    // 良し!
} else {
    // 失敗!
    // $model->getErrors() を使う
}
```


77
アクションを作成する <span id="creating-action"></span>
78 79 80
--------------------

次に、この新しいモデルを使う `entry` アクションを `site` コントローラに作る必要があります。
81
アクションを作成して使うプロセスについては、[こんにちは、と言う](start-hello.md) の節で既に説明されています。
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

```php
<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
use app\models\EntryForm;

class SiteController extends Controller
{
    // ... 既存のコード ...

    public function actionEntry()
    {
        $model = new EntryForm;

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
101
            // $model に有効なデータを受け取った場合
102

103
            // ここで $model について何か意味のあることをする ...
104 105 106

            return $this->render('entry-confirm', ['model' => $model]);
        } else {
107
            // ページの初期表示か、または、何か検証エラーがある場合
108 109 110 111 112 113
            return $this->render('entry', ['model' => $model]);
        }
    }
}
```

114 115 116
アクションは最初に `EntryForm` オブジェクトを生成します。
次に、モデルに `$_POST` のデータ、Yii においては [[yii\web\Request::post()]] によって提供されるデータを投入しようと試みます。
モデルへのデータ投入が成功した場合(つまり、ユーザが HTML フォームを送信した場合)、アクションは[[yii\base\Model::validate()|validate()]] を呼んで、入力された値が有効なものであるかどうかを確認します。
117 118

> Info|情報: `Yii::$app` という式は [アプリケーション](structure-applications.md) インスタンスを表現します。
119
  これはグローバルにアクセス可能なシングルトンです。
120
  これは、また、特定の機能性をサポートする `request``response``db` などのコンポーネントを提供する [サービスロケータ](concept-service-locator.md) でもあります。
121
  上記のコードでは、アプリケーションインスタンスの `request` コンポーネントが `$_POST` データにアクセスするために使われています。
122 123

すべてが適正である場合、アクションは `entry-confirm` という名前のビューを表示して、データの送信が成功したことをユーザに確認させます。
124
データが送信されなかったり、データがエラーを含んでいたりする場合は、`entry` ビューが表示され、その中で HTML フォームが (もし有れば) 検証エラーのメッセージとともに表示されます。
125

126 127
> Note|注意: この簡単な例では、有効なデータ送信に対して単純に確認ページを表示しています。
  実際の仕事では、[フォーム送信の諸問題](http://en.wikipedia.org/wiki/Post/Redirect/Get) を避けるために、[[yii\web\Controller::refresh()|refresh()]] または [[yii\web\Controller::redirect()|redirect()]] を使うことを考慮すべきです。
128 129


130
ビューを作成する <span id="creating-views"></span>
131 132
----------------

133
最後に、`entry-confirm``entry` という名前の二つのビューファイルを作成します。
134 135 136 137 138 139 140 141
今まさに説明したように、これらが `entry` アクションによって表示されます。

`entry-confirm` ビューは単純に名前とメールのデータを表示するものです。このビューは `views/site/entry-confirm.php` というファイルに保存しなければなりません。

```php
<?php
use yii\helpers\Html;
?>
142
<p>あなたは次の情報を入力しました</p>
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

<ul>
    <li><label>名前</label>: <?= Html::encode($model->name) ?></li>
    <li><label>メール</label>: <?= Html::encode($model->email) ?></li>
</ul>
```

`entry` ビューは HTML フォームを表示します。これは `views/site/entry.php` というファイルに保存しなければなりません。

```php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'name') ?>

    <?= $form->field($model, 'email') ?>

    <div class="form-group">
        <?= Html::submitButton('送信', ['class' => 'btn btn-primary']) ?>
    </div>

<?php ActiveForm::end(); ?>
```

このビューは HTML フォームを構築するのに、[[yii\widgets\ActiveForm|ActiveForm]] と呼ばれる強力な [ウィジェット](structure-widgets.md) を使います。
171
ウィジェットの `begin()` メソッドと `end()` メソッドが、それぞれ、フォームの開始タグと終了タグをレンダリングします。
172 173 174
この二つのメソッドの呼び出しの間に、[[yii\widgets\ActiveForm::field()|field()]] メソッドによってインプットフィールドが作成されます。
最初のインプットフィールドは "name" のデータ、第二のインプットフィールドは "email" のデータのためのものです。
インプットフィールドの後に、[[yii\helpers\Html::submitButton()]] メソッドが呼ばれて、送信ボタンを生成しています。
175 176


177
試してみる <span id="trying-it-out"></span>
178 179
----------

180
どのように動作するかを見るために、ブラウザで下記の URL をアクセスしてください。
181 182 183 184 185

```
http://hostname/index.php?r=site/entry
```

186 187 188
二つのインプットフィールドを持つフォームを表示するページが表示されるでしょう。
それぞれのインプットフィールドの前には、どんなデータを入力すべきかを示すラベルがあります。
何も入力せずに、あるいは、無効なメールアドレスを入力して送信ボタンをクリックすると、それぞれ問題のあるインプットフィールドの後ろにエラーメッセージが表示されます。
189 190 191 192 193 194 195 196

![検証エラーのあるフォーム](images/start-form-validation.png)

有効な名前とメールアドレスを入力してから送信ボタンをクリックすると、たった今入力したデータを表示する新しいページが表示されます。

![データ入力の確認](images/start-entry-confirmation.png)


197
### 魔法の説明<span id="magic-explained"></span>
198

199
あなたは、舞台裏で HTML フォームがどのように動いているのか、不思議に思うかも知れません。
200
なぜなら、フォームが、ほとんど魔法のように、各インプットフィールドのラベルを表示し、データを正しく入力しなかった場合には、ページをリロードすることなく、エラーメッセージを表示するからです。
201

202
そう、データの検証は、最初に JavaScript を使ってクライアント側で実行され、次に PHP によってサーバ側で実行されます。
203
[[yii\widgets\ActiveForm]] は、賢いことに、`EntryForm` で宣言した検証規則を抽出し、それを実行可能な JavaScript コードに変換して、JavaScript を使ってデータ検証を実行します。
204
ブラウザで JavaScript を無効にした場合でも、`actionEntry()` メソッドで示されているように、サーバ側での検証は引き続き実行されます。
205 206
これにより、どのような状況であっても、データの有効性が保証されます。

207 208
> Warning|警告: クライアント側の検証は、ユーザにとってのより良い使い心地のために利便性を提供するものです。
  クライアント側の検証の有無にかかわらず、サーバ側の検証は常に必要とされます。
209

210
インプットフィールドのラベルは、モデルのプロパティ名を使用して、`field()` メソッドによって生成されます。
211 212
例えば、`name` というプロパティから `Name` というラベルが生成されます。

213
ビューの中で、下記のコードのように、ラベルをカスタマイズすることも出来ます。
214 215 216 217 218 219 220 221 222 223 224

```php
<?= $form->field($model, 'name')->label('お名前') ?>
<?= $form->field($model, 'email')->label('メールアドレス') ?>
```

> Info|情報: Yii はこのようなウィジェットを数多く提供して、複雑で動的なビューを素速く作成することを手助けしてくれます。
  後で学ぶように、新しいウィジェットを書くことも非常に簡単です。
  あなたは、将来のビュー開発を単純化するために、多くのビューコードを再利用可能なウィジェットに変換したいと思うことでしょう。


225
まとめ <span id="summary"></span>
226 227 228 229 230 231 232 233 234 235
------

ガイドのこの節においては、MVC デザインパターンの全ての部分に触れました。
そして、ユーザデータを表現し、当該データを検証するモデルクラスを作成する方法を学びました。

また、ユーザからデータを取得する方法と、ブラウザにデータを表示して返す方法も学びました。
この作業は、アプリケーションを開発するときに、多大な時間を必要とするものになり得るものです。
しかし、Yii はこの作業を非常に容易にする強力なウィジェットを提供しています。

次の節では、ほとんど全てのアプリケーションで必要とされるデータベースを取り扱う方法を学びます。