フォーム
Nibiruの静的ファクトリでフォームを流暢に構築します。
Nibiruのフォームは、\Nibiru\Factory\Formクラスの静的メソッドを呼び出すことで流暢に構築されます。各呼び出しでは、HTMLフラグメントが内部の静的なバッファに追加されます。最後に、Form::addForm()メソッドはバッファを<form>要素で囲み、レンダリングされたHTML文字列を返します。
ファクトリをインポートする
Section titled “ファクトリをインポートする”use Nibiru\Factory\Form;これが唯一必要な use です。すべての入力タイプはこのクラスの静的メソッドです。
メソッドの完全なカタログ
Section titled “メソッドの完全なカタログ”歴史的な命名により、3つのメソッドのバリエーションがあります。
addInputType* — 実際の <input> 要素用
Section titled “addInputType* — 実際の <input> 要素用”addInputTypeText addInputTypePassword addInputTypeEmailaddInputTypeDate addInputTypeDatetime addInputTypeColoraddInputTypeRadio addInputTypeCheckbox addInputTypeSwitchaddInputTypeSubmit addInputTypeTextareaaddType* — 非 <input> フォーム要素用
Section titled “addType* — 非 <input> フォーム要素用”addTypeFileUpload addTypeHidden addTypeImageSubmitaddTypeNumber addTypeRange addTypeResetaddTypeSearch addTypeTelefon addTypeUrladdTypeButton addTypeLabeladdSelect / addSelectOption — <select> と <option> のため
Section titled “addSelect / addSelectOption — <select> と <option> のため”addSelect addSelectOptionレイアウトヘルパー
Section titled “レイアウトヘルパー”addOpenDiv addCloseDiv addOpenAny addCloseAnyaddOpenSpan addCloseSpanライフサイクル
Section titled “ライフサイクル”create / reset the static buffer; call before building a new formaddForm / wrap the buffer in <form>...</form> and return as a stringフォームの構築
Section titled “フォームの構築”use Nibiru\Factory\Form;
Form::create(); / reset the static buffer
Form::addOpenDiv(['class' => 'form-group']);Form::addTypeLabel(['for' => 'login', 'value' => 'Username']);Form::addInputTypeText([ 'name' => 'login', 'id' => 'login', 'class' => 'form-control', 'required' => 'required', 'placeholder' => 'Type your name…',]);Form::addCloseDiv();
Form::addOpenDiv(['class' => 'form-group']);Form::addTypeLabel(['for' => 'password', 'value' => 'Password']);Form::addInputTypePassword([ 'name' => 'password', 'id' => 'password', 'class' => 'form-control', 'required' => 'required',]);Form::addCloseDiv();
Form::addInputTypeSubmit(['value' => 'Sign in', 'class' => 'btn btn-primary']);
$html = Form::addForm([ 'method' => 'POST', 'action' => '/login', 'name' => 'loginForm',]);$html をビューに渡します:
View::assign(['loginForm' => $html]);``````smarty<div class="card-body"> {$loginForm nofilter}</div>(nofilter は Form::addForm() がすでにレンダリングされた HTML を返すためです — Smarty ではそれ以外をエスケープします。)
オプション付きで選択する
Section titled “オプション付きで選択する”Form::addSelect(['name' => 'country', 'class' => 'form-control', 'id' => 'country']);Form::addSelectOption(['value' => 'at', 'label' => 'Austria']);Form::addSelectOption(['value' => 'lu', 'label' => 'Luxembourg']);Form::addSelectOption(['value' => 'us', 'label' => 'United States']);addSelect は <select> を開き、オプション収集状態をキューに登録します。各 addSelectOption はそれに追加されます。ラップする </select> は次の非オプション呼び出しが発生したときに自動的に生成されます。
ラジオグループ
Section titled “ラジオグループ”foreach (['standard', 'admin', 'editor'] as $r) { Form::addInputTypeRadio([ 'name' => 'role', 'value' => $r, 'id' => "role-$r", ]); Form::addTypeLabel(['for' => "role-$r", 'value' => ucfirst($r)]);}ファイルアップロード
Section titled “ファイルアップロード”Form::addTypeFileUpload([ 'name' => 'avatar', 'accept' => 'image/png,image/jpeg',]);フォームで enctype を忘れないでください。
Form::addForm([ 'method' => 'POST', 'action' => '/profile/upload', 'enctype' => 'multipart/form-data',]);隠された CSRF トークン
Section titled “隠された CSRF トークン”Form::addTypeHidden([ 'name' => 'csrf', 'value' => bin2hex(random_bytes(16)),]);(値を $_SESSION['csrf'] に保存し、POST 時に検証してください。)
レイアウトヘルパー
Section titled “レイアウトヘルパー”addOpenDiv / addCloseDiv と addOpenAny / addCloseAny を使用すると、同じフレuent ストリーム内で Bootstrap スタイルのレイアウトを作成できます。
Form::addOpenDiv(['class' => 'row']); Form::addOpenDiv(['class' => 'col-md-6']); Form::addInputTypeText(['name' => 'first']); Form::addCloseDiv(); Form::addOpenDiv(['class' => 'col-md-6']); Form::addInputTypeText(['name' => 'last']); Form::addCloseDiv();Form::addCloseDiv();addOpenAny([…, 'tag' => 'fieldset']) は任意の他のタグを開きます;addCloseAny([…, 'tag' => 'fieldset']) はそれを閉じます。
内部でどのように動作するか
Section titled “内部でどのように動作するか”フォームのレンダリングは文字列ベースです。DOMベースではありません。各タイプクラスはcore/c/type<X>.phpにあり、プレースホルダーを含むHTMLテンプレートが含まれています:
private function _setElement() { $this->_element = '<input type="text" name="NAME" value="VALUE" ' . 'placeholder="PLACEHOLDER" maxlength="MAXLENGTH" ID CLASS ' . 'REQUIRED DATA>' . "\n";}ファクトリーは、あなたの $attributes 配列を FormAttributes::loadAttributeValues() に渡します。このメソッドは、各プレースホルダーを対応する値で置き換えます。空の値がある場合は、プレースホルダーが削除されるため、属性が空文字列でレンダリングされることはありません。
これがなぜ のみ知られたキーが機能するか — 'name', 'value', 'placeholder', 'class', 'id', 'required', 'data' が認識され、任意のキーは静かにドロップされるのか。
生産からのパターン
Section titled “生産からのパターン”thorax.nibiru-framework.com 上の formsController は、コンストラクタで連絡先フォームを構築し、プロパティに割り当てます。
namespace Nibiru;use Nibiru\Adapter\Controller;use Nibiru\Factory\Form;
class formsController extends Controller { private string $form;
public function __construct() { parent::__construct(); Form::create(); Form::addTypeLabel(['value' => 'Full Name', 'for' => 'full-name']); Form::addInputTypeText([ 'name' => 'full-name', 'id' => 'full-name', 'required' => 'required', 'class' => 'contacts-input form-control', ]); / ...more fields... $this->form = Form::addForm([ 'name' => 'newregister', 'method' => 'post', 'action' => '/forms/submit', ]); }
public function pageAction() { View::assign(['form' => $this->form]); }}これにより、コントローラーのアクションが小さくなります — フォームはテンプレートにレンダリングするための一行です。
一般的な落とし穴
Section titled “一般的な落とし穴”Form::create()を忘れている。 バッファは静的です。create()がないと、最後にあったもの(長時間動作する PHP プロセス間を含む)に連結されます。- Smarty が HTML をエスケープしている。 レンダリングされた文字列を出力するときには
nofilter(または|nofilter)を追加します。 - カスタム属性が静かに無視される。 各タイプは固定のプレースホルダーキーを受け付けます。
data-*属性(展開されます)のためにdataキーを使用しますが、真に任意の属性はドロップされます。 - 自動的な XSS エスケープがない。 フォーム層は文字列ベースです。ユーザー入力をデフォルトの
valueとしてレンダリングする場合、ファクトリに渡す前に自分でエスケープしてください。 addInputType…vsaddType…の混同。 不確実な場合は、core/c/type<X>.phpファイル名を見てください — タイプの HTML 要素が<input type="X">であればaddInputType<X>を使用し、それ以外はaddType<X>を使用します。addSelectは唯一の例外です(プレフィックスなしでaddSelect)。
フォームバリデーション
Section titled “フォームバリデーション”Nibiru はサーバーサイドバリデーションを搭載していません。一般的なパターン:
Respect/Validationによる宣言的なチェック(既に多くのプロダクションNibiruアプリで使用されています)。- フォームタイプごとの
validate()プラグインを含むモジュール。 - HTML5の
required、pattern、min/maxが第一線の防御です。