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.