Zum Inhalt springen
Nibiru docsv0.9.2

Formulare

Bauen Sie Formulare flüssig mit der statischen Fabrik von Nibiru.

Stable Reading time ~ 4 min Edit on GitHub

Formulare in Nibiru werden flüssig durch Aufruf statischer Methoden auf \Nibiru\Factory\Form erstellt. Jeder Aufruf fügt einen HTML-Teil einem internen statischen Puffer hinzu; ein abschließender Form::addForm() verpackt den Puffer in ein <form>-Element und gibt die gerenderte HTML-Zeichenfolge zurück.

use Nibiru\Factory\Form;

Das ist der einzige use, den Sie benötigen. Jeder Eingabetyp ist eine statische Methode dieser Klasse.

Es gibt drei Arten der Methode, nach historischem Benennung.

addInputType* — für tatsächliche <input>-Elemente

Abschnitt betitelt „addInputType* — für tatsächliche <input>-Elemente“
addInputTypeText addInputTypePassword addInputTypeEmail
addInputTypeDate addInputTypeDatetime addInputTypeColor
addInputTypeRadio addInputTypeCheckbox addInputTypeSwitch
addInputTypeSubmit addInputTypeTextarea
addTypeFileUpload addTypeHidden addTypeImageSubmit
addTypeNumber addTypeRange addTypeReset
addTypeSearch addTypeTelefon addTypeUrl
addTypeButton addTypeLabel

addSelect / addSelectOption — für <select> + <option>

Abschnitt betitelt „addSelect / addSelectOption — für <select> + <option>“
addSelect addSelectOption
addOpenDiv addCloseDiv addOpenAny addCloseAny
addOpenSpan addCloseSpan
create / reset the static buffer; call before building a new form
addForm / wrap the buffer in <form>...</form> and return as a string
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',
]);

Übergeben Sie $html an Ihre Ansicht:

View::assign(['loginForm' => $html]);
``````smarty
<div class="card-body">
{$loginForm nofilter}
</div>

(nofilter, da Form::addForm() bereits gerenderte HTML zurückgibt – Smarty würde andernfalls entwerten.)

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 öffnet den <select> und fügt den Zustand der Optionensammlung zur Warteschlange hinzu; jede addSelectOption hängt an diese an; das umgebende </select> wird automatisch ausgegeben, wenn der nächste nicht-Optionen-Aufruf stattfindet.

foreach (['standard', 'admin', 'editor'] as $r) {
Form::addInputTypeRadio([
'name' => 'role', 'value' => $r, 'id' => "role-$r",
]);
Form::addTypeLabel(['for' => "role-$r", 'value' => ucfirst($r)]);
}
Form::addTypeFileUpload([
'name' => 'avatar',
'accept' => 'image/png,image/jpeg',
]);

Achten Sie nicht auf enctype im Formular zu vergessen:

Form::addForm([
'method' => 'POST',
'action' => '/profile/upload',
'enctype' => 'multipart/form-data',
]);
Form::addTypeHidden([
'name' => 'csrf',
'value' => bin2hex(random_bytes(16)),
]);

(Speichern Sie den Wert in $_SESSION['csrf'] und überprüfen Sie ihn bei POST.)

addOpenDiv / addCloseDiv und addOpenAny / addCloseAny ermöglichen es Ihnen, Bootstrap-artige Layouts innerhalb des gleichen flüssigen Streams zu erstellen:

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']) öffnet einen beliebigen anderen Tag; addCloseAny([…, 'tag' => 'fieldset']) schließt ihn.

Die Formulardarstellung ist zeichenkettenbasiert, nicht DOM-basiert. Jede Typklasse befindet sich unter core/c/type<X>.php und enthält eine HTML-Vorlage mit Platzhaltern:

core/c/typetext.php
private function _setElement() {
$this->_element = '<input type="text" name="NAME" value="VALUE" '
. 'placeholder="PLACEHOLDER" maxlength="MAXLENGTH" ID CLASS '
. 'REQUIRED DATA>' . "\n";
}

Der Fabrikprozess übergibt Ihren $attributes-Array an FormAttributes::loadAttributeValues(), das jedes Platzhalterzeichen durch den entsprechenden Wert ersetzt. Leere Werte werden gelöscht, sodass die Attribute nicht mit leeren Zeichenfolgen gerendert werden.

Dies ist der Grund, warum nur bekannte Schlüssel funktionieren'name', 'value', 'placeholder', 'class', 'id', 'required', 'data' werden erkannt; beliebige Schlüssel werden stumm abgeworfen.

Der formsController auf thorax.nibiru-framework.com baut sein Kontaktformular im Konstruktor und weist es einer Eigenschaft zu:

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]);
}
}

Dies behält die Aktionen des Controllers klein – das Formular ist eine Zeile, um im Template gerendert zu werden.

  • Versehen mit Form::create(). Der Puffer ist statisch. Ohne create() werden Sie anhängen, was zuletzt da war (einschließlich über Anfragen in langlaufenden PHP-Prozessen).
  • Smarty maskiert das HTML. Fügen Sie nofilter (oder |nofilter) hinzu, wenn Sie die gerenderte Zeichenfolge ausgeben.
  • Benutzerdefinierte Attribute werden stumm geschwiegen ignoriert. Jeder Typ akzeptiert eine festgelegte Menge an Platzhalter-Schlüsseln. Verwenden Sie den data-Schlüssel für data-*-Attribute (die erweitert werden), aber wirklich willkürliche Attribute werden verworfen.
  • Keine automatische XSS-Verschleierung. Die Form-Ebene ist zeichenkettenbasiert. Wenn Sie Benutzereingaben als Standardwert value rendern, verschleiern Sie sie selbst vor dem Übergeben an die Fabrik.
  • Verwirrung zwischen addInputType… und addType…. Bei Zweifeln schauen Sie sich den Dateinamen in core/c/type<X>.php an — wenn das HTML-Element des Typs <input type="X"> ist, verwenden Sie addInputType<X>, andernfalls addType<X>. addSelect ist die einzige Ausnahme (nur addSelect, ohne Präfix).

Nibiru bietet keine serverseitige Validierung. Häufige Muster:

  • Respekt/Validierung für deklarative Überprüfungen (bereits in vielen Produktionsanwendungen von Nibiru).
  • Ein Modul mit einem validate()-Plugin pro Formulartyp.
  • HTML5-Attribute wie required, pattern, min/max als erstes Schutzmaßnahme.