UnsplashのAaron Burdenが撮影した写真
目次
PhalconにはFormをコンポーネント化するためのFormクラスが用意されています。
業務で使っているので、この記事にその使い方を簡単にメモします。
Formクラスを使うと、バリデーションエラーで元の画面に戻ってきたときに自動で$_POSTの値をセットしてくれたり、なにかと便利です。
OS:Windows11 Home / WSL(Ubuntu20.04)
php:v7.4.33
phalcon:4.0.6
Phalcon DevTools:v4.2.0
DB:mysql v8.0.34
以下のカラムを持つUsersテーブルにCRUDするためのFormを作成します。
【カラム】
・id
・name
・password
本題に入る前に上記のUsersテーブルを作成してください。
この記事では、Usersテーブルにadd(データを作成する)する機能を実装します。
Formクラスを使うために、以下の作業をします。
①config.phpにformをまとめるフォルダのパスを追記する
②loader.phpに1行追記
③formsフォルダを作成する
④formファイルを作成する
⑤Controllerを編集する
⑥Viewでformを使う
それではさっそく①から始めます。
後程Formをまとめるフォルダを作成するので、config.phpにフォルダのパスを追記します。
/app/config/config.phpに以下の赤字の1行を追記します。
~~省略~~
return new \Phalcon\Config([
'database' => [
~~省略~~
],
'application' => [
'appDir' => APP_PATH . '/',
'controllersDir' => APP_PATH . '/controllers/',
'modelsDir' => APP_PATH . '/models/',
'migrationsDir' => APP_PATH . '/migrations/',
'viewsDir' => APP_PATH . '/views/',
'pluginsDir' => APP_PATH . '/plugins/',
'libraryDir' => APP_PATH . '/library/',
'cacheDir' => BASE_PATH . '/cache/',
'baseUri' => '/',
'formsDir' => 'APP_PATH . '/forms/',
]
]);
/app/config/loader.phpに以下赤字部分の1行を追記します。
<?php
$loader = new \Phalcon\Loader();
/**
* We're a registering a set of directories taken from the configuration file
*/
$loader->registerDirs(
[
$config->application->controllersDir,
$config->application->modelsDir,
$config->application->formsDir,
]
)->register();
次にFormをまとめるためのフォルダを作成します。
/app/formsとなるよう「forms」フォルダを作成してください。
③で作成したformsフォルダにUserForm.phpファイルを作成し、以下のように記述してください。
<?php
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Hidden;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Password;
use Phalcon\Validation;
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\Uniqueness as UniquenessValidator;
use Phalcon\Validation\Validator\Regex as RegexValidator;
class UserForm extends Form{
public function initialize(){
$user_id = new Hidden("id");
$this->add($user_id);
$name = new Text("name");
$name->setLabel("名前");
$name->addValidator(
new PresenceOf(
[
"message" => "名前は必須です"
]
)
);
$name->addValidator(
new UniquenessValidator(
[
"model" => new Users(),
"message" => "この名前は既に使用されています",
]
)
);
$this->add($name);
$password = new Password("password");
$password->setLabel("パスワード");
$password->addValidator(
new RegexValidator(
[
"pattern" => "/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8, 16}/u",
"message" => "パスワードは大文字、小文字、数字を含む8-16文字を指定してください",
]
)
);
$this->add($password);
}
}
なお、以下のリンクからFormクラスで使える要素の一覧とバリデーションの一覧を確認できます。
※Formの要素一覧:https://docs.phalcon.io/4.0/en/forms#elements
※Validation一覧 :https://docs.phalcon.io/4.0/en/validation#validators
UsersController.phpのaddActionを以下のように編集してください。
public function addAction(){
$form = new UserForm();
$this->view->form = $form;
//POSTされた時の処理
if($_POST['operation'] == "send"){
$user = new Users();
$user->name = $_POST['name'];
$user->password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$form = new UserForm();
//バリデーション判定で条件分岐
if($form->isValid($_POST) && $user->save()){
//バリデーションOKの時の処理
return $this->response->redirect("users/index");
}else{
//バリデーションNGの時の処理
$this->view->errorMessages = $form->getMessages();
}
}
}
最後にadd.phtmlを以下のように編集します。
<h2>users/add</h2>
<!-- エラーメッセージを表示 -->
<?php
if(!empty($errorMessages)){
foreach($errorMessages as $message){
echo "<p style='color:red;'>{$message}</p>";
}
}
?>
<form action="#" method="post">
<p><?php echo $form->label("name");?></p>
<p><?php echo $form->render("name");?></p>
<p><?php echo $form->label("password");?></p>
<p><?php echo $form->render("password");?></p>
<button type="submit" name="operation" value="send">登録</button>
</form>
以上でFormクラスでのFormのコンポーネント化は完了です!
こんな感じで表示されていればOKです。
Formクラスでバリデーションをするので、もしモデルにバリデーションを記述している場合はモデルからバリデーションを削除してください。
モデルにバリデーションを記述する場合は以下のようになっているかと思うので、赤字部分に該当する部分を丸ごと削除してください。
~~省略~~
class Users extends \Phalcon\Mvc\Model
{
public $id;
public $name;
public $password;
public function initialize()
{
$this->setSchema("ouchibar2");
$this->setSource("users");
}
public function validation(){
$validator = new Validation();
$validator->add(
["name", "password"],
new PresenceOf([
"message" => [
"name" => "nameは必須です",
"password" => "passwordは必須です"
]
])
);
$validator->add(
"password",
new StringLength(
[
"max" => 16,
"min" => 8,
"messageMaximum" => "passwordは8-16文字で入力してください",
"messageMinimun" => "passwordは8-16文字で入力してください",
"includeMaximum" => true,
"includeMinimum" => false
]
)
);
return $validator->validate($_POST);
}
~~省略~~
}