Wie geht ihr komplexe Formular-Aufbau/Verarbeitung an ..

deostift

Erfahrenes Mitglied
Hallo zusammen,

ich wollte mal nachfragen wie Ihr das leidige Thema "Formulare" angeht. Da gibt es ja einiges zu beachten:

- Abwehren von Hackversuchen
- Setzen der selektierten Werte beim Reload
- Trennung der PHP-Verarbeitung vom HTML / Template
...

Die einen knallen die Verarbeitung / Fehlerkontrolle in das HTML-Formular, andere nutzen selbergeschriebene Funktionen um Select, Input, etc. Felder anhand von Parametern aufbauen zu lassen.

So sind gerade komplexe Formulare mit einer Vielzahl von dynamischen Selektions-Möglichkeiten sehr schwer "zu lesen". Speziell für Dritte ist das Durchackern des Super-Globals / PHP / HTML / CSS - MischMasch sehr schwer.

Deshalb die Frage: Gibt es hierzu "Template-Systeme" oder Guidelines wie mal sauber solche Formulare aufbaut oder bleibt das einem selbst überlassen :rolleyes:

Danke und bis morgen ;)

Deo
 
Das ist ja richtiger Wurstcode. Genauso finde ich es unübersichtlich und schlecht wiederverwendbar.
M.E. sollte man unbedingt auf einen OOP Ansatz zurückgreifen.
Sowohl zum generieren, als auch zum validieren. Das sollte man getrennt betrachten.

Beim generieren ist es wohl ratsam einen Registry Pattern zu benutzen. Z.B. gibt es eine abstrakte Klasse für die Formularobjekte. Dann ist jedes mögliche Formularteil eine Klasse.
Da ist die Funktionalität enthalten diese zu rendern und die eventuell vorher eingegebenen oder aus einer DB stammenden Inhalte einzusetzen.
Außerdem sollte ein Zugriff auf die Eigenschaften von "außen" möglich sein. So kann man z.B. Fehlermeldungen direkt an die entsprechenden Felder weitergeben.

Bei der Auswertung des Formulars solltest du auch wieder ein Designkonzept haben.
Es empfehlen sich wieder eine abstrakte Klasse und diese implementierende Klassen, die die jeweiligen Regeln enthalten.
Du übergibst ein Formularfeld (bzw. einen Array an Formularfeldern, falls die Regel mehrere betrifft wie z.B. gleiches Passwort zweimal), eine Fehlermeldung und den Namen der Regel (oder gleich ein Objekt anhand der genannten Parameter erstellen und an die Registry übergeben).

Die Fehlermeldungen kannst du dann entweder gesammelt ausgeben oder wieder zurück in die Beschreibung der jeweiligen Formularfelder zurück injizieren.

Einen ähnlichen Ansatz verfolgt glaube ich auch PEAR::HTML_Quickform.
Benutze da aber lieber eine eigene Lösung.

Ich hoffe du konntest mir folgen. Wenn dir einige der Begriffe nicht geläufig sind, frag einfach nochmal nach und ich oder jemand anderes wird sie dir erklären oder dir passende Links geben.
 
Hallo Ihr beiden,

danke für die Hinweise :) @Hamster: So sah mein Code früher auch aus ;)

Inzwischen code ich in dieser Art (liese sich auch leicht mit OOP umsetzen):


PHP:
function printFormSelect ($selectName, $arrOption, $selection, $defaultOption="") {
	
	echo '<select name="'.$selectName.'">'."\n";
	if($defaultOption!="") echo '<option>'.$defaultOption.'</option>';
	foreach ($arrOption as $key => $value)
	{
		echo '<option value="'.$value.'"';
		if ($selection == $value)
			echo ' selected="selected"';
		echo '>'.$value.'</option>'."\n";
	} // foreach
	echo '</select>'."\n";
}  // function printFormSelect()

Das ist zum Beispiel ne Funktion um sich ein Select-Feld bauen zu lassen. Allerdings stört es mich noch, dass ich hier keine Trennung von der View hinbekomme ... also immer noch HTML erzeuge :( Aber wenn ich das Select-Feld über eine Schleife im HTML-Code erzeuge ist das auch doof *hach*

Im HTML-Formular rufe ich das wie folgt auf:

Code:
printFormSelect ('selectName_'.$counter, array("Hund","Katze","Maus"), $_POST['selectName_'.$counter]);

Also so in der Art ... Ich weiss nun nicht ob das eine der elegantesten Formen ist. An OOP müsste ich mich in meinem Projekt erst heranwagen - will aber so bald wie möglich umsteigen :)

Aber Grundsätzlich, rythms ... Holst Du Dir am Anfang der z.B. Formular.php die ganzen $HTTP_POST_VARS ab, prüfst die auf Hackgeschichten/Sinn etc. und gibst diese dann an die Member-Variablen der jeweiligen Formular-Klassenobjekte weiter und stößt dann im HTML-Formular-Code dann nur noch die Objekt-Methoden zum Genieren an? Oder wie machst Du das vom Ablauf her ..

Kannst Du vielleicht mal ein wenig Beispiel-Code wo rausschnippeln bzw. wie Du den Aufbau machst... also z.B. zu Beginn die Super-Globals auslesen, checken, Member-Vars mit Set-Funktionen füllen...

Wie funktioniert denn das wenn ich eine "Select"-Klassenobjekt zum Beispiel habe ... kann ich das und dessen Zustände irgendwie über Sessions am Leben erhalten oder "tötet" mir jedes "submit" mein Objekt und ich muss es beim Reload neu aufbauen?

Danke Dir, besonders auch für Deinen Denkanstoß :)

Deo
 
Zuletzt bearbeitet:
HTML generieren musst du schon, anders geht es schlecht.
Allerdings reicht es ja, wenn du nur die Formularfelder generierst.
Du könntest dir das dann als Array zurückgeben lassen in der Form:
Code:
Array(
  ['name'] Array(
       'field_html' => '<input type,....',
       'field_name' => 'name',
       'field_desc' => 'Beschreibung des Feldes'
)
)
Das kannst du dann in deinem View weiterverwenden.
Eventuell solltest du dir dabei gleich überlegen, ob du Id's automatisch generieren willst (z.b. anhand von Formular-Name und Feld-Name. Das kann nützlich werden, wenn du labels verwenden willst.
Das allgemeine Stylen geht dann per CSS.

Der Ablauf ist folgender:
- Im Code werden die Formular-Registry und die Regel-Registry erstellt.
- Die Regeln werden geprüft
- Wenn die Regeln nicht alle validieren wird der HTML Code der Formular-Felder generiert und ausgegeben, eventuell werden noch Fehlermeldungen eingespeist.
- Wenn die Regeln validieren wird die entsprechende Aktion durchgeführt. Ich kann mir mit einem Methodenaufruf alle Werte in einem Array holen.

Zustände gibt es nur drei:
- leeres Formular
- ausgefülltes, fehlerhaftes Formular mit Daten
- validierte Daten, ohne Formular

Btw: In Funktionen gibt man nichts mit echo aus, sondern nur mit return zurück. Das gehört zum guten Stil.
 
Re: AW: Wie geht ihr komplexe Formular-Aufbau/Verarbeitung an ..

Hi,

Das ist zum Beispiel ne Funktion um sich ein Select-Feld bauen zu lassen. Allerdings stört es mich noch, dass ich hier keine Trennung von der View hinbekomme ... also immer noch HTML erzeuge :( Aber wenn ich das Select-Feld über eine Schleife im HTML-Code erzeuge ist das auch doof *hach*

Ich handle meine Formulare momentan in etwa so:
PHP:
<?php
if (isset($_POST['np_submit'])) {
	$id = $nopaste->insertEntry($_POST['np_nick'], $_POST['np_desc'], $_POST['np_code'], $_POST['np_lang']);
	header('Location: ' . $_SERVER['PHP_SELF'] . '?np_id=' . $id);
} else {
	$nopaste->show();
}
?>
Wenn das Formular abgeschickt wurde, werden die Daten von der entsprechenden Klasse weiterverarbeitet. Danach wird auf den neuen Eintrag weitergeleitet, so werden auch die $_POST-Variablen gelöscht.
Ansonsten zeigt die Klasse das Template für das Formular. Das Template ist dem User überlassen, aufgrund der Flexibilität, da man ja nicht wissen kann, ob die gewählten Eingabefeldernamen schon in der bestehenden Webseite verwendet werden.

Bezüglich des Validieren der Daten, könntest du einen Blick auf das PEAR Package Validate werfen.


Gruß
Marvin
 
Zuletzt bearbeitet:
Re: AW: Wie geht ihr komplexe Formular-Aufbau/Verarbeitung an ..

Hi,
Ich handle meine Formulare momentan in etwa so:
PHP:
<?php
if (isset($_POST['np_submit'])) {
	$id = $nopaste->insertEntry($_POST['np_nick'], $_POST['np_desc'], $_POST['np_code'], $_POST['np_lang']);
	header('Location: ' . $_SERVER['PHP_SELF'] . '?np_id=' . $id);
} else {
	$nopaste->show();
}
?>
Wenn das Formular abgeschickt wurde, werden die Daten von der entsprechenden Klasse weiterverarbeitet. Danach wird auf den neuen Eintrag weitergeleitet, so werden auch die $_POST-Variablen gelöscht.
Und das schmeißt mit Notices, wenn die anderen Variablen nicht gesetzt sind.
Sag jetzt bitte nicht, das die aufgerufene Methode dann auch noch direkt die Daten in die DB einträgt?
Ansonsten zeigt die Klasse das Template für das Formular. Das Template ist dem User überlassen, aufgrund der Flexibilität, da man ja nicht wissen kann, ob die gewählten Namen der Eingabefelder schon in der bestehenden Webseite verwendet werden.
Wenn man ein Formular erstellt, wird entweder dieses Formular oder ein anderes aufgerufen. Es ist also egal, ob die Feldnamen schon einmal vorkommen.
Welches Formular abgeschickt wurde, erkennt man entweder auf der Zeilseite oder anhand der eingegebenen Daten im Bezug zu den vorhandenen Regeln.
Bezüglich des Validieren der Daten, könntest du einen Blick auf das PEAR Package Validate werfen.
Oder doch direkt die PHP nativen Funktionen: http://php.net/filter (PHP 5.2 bzw. 5.1.6)
 
Hallo rythms,
mit den Notices hast du natürlich Recht. Ich lasse Variablen schon vorher überprüfen, da alle Felder momentan Pflichtfelder sind, und lasse ggf. eine Fehlermeldung angezeigt. Habe den Teil aber rausgenommen, da es ein Beispiel für eine OOP-Variante sein sollte.
Die Daten werden nach den entsprechenden DBMS Standards escape't und nach ihrem Typ (nicht) in Anführungszeichen gesetzt.

Was ist wenn alle Formulare an ein Script gesendet werden, wie soll das Script erkennen welches Formular abgeschickt wurde?

Gruß
Marvin
 
Hallo rythms,
mit den Notices hast du natürlich Recht. Ich lasse Variablen schon vorher überprüfen, da alle Felder momentan Pflichtfelder sind, und lasse ggf. eine Fehlermeldung angezeigt. Habe den Teil aber rausgenommen, da es ein Beispiel für eine OOP-Variante sein sollte.
Die Daten werden nach den entsprechenden DBMS Standards escape't und nach ihrem Typ (nicht) in Anführungszeichen gesetzt.
Dann ist dein Beispiel aber trotzdem schlecht.
Entweder hat es mit dem Formular Handling nichts zu tun, oder du mischt da DB und Formular Handling in einer Klasse. Das ist auf jeden Fall ein No-Go.

Was ist wenn alle Formulare an ein Script gesendet werden, wie soll das Script erkennen welches Formular abgeschickt wurde?
Anhand der ausgefüllten Felder. Das Script weiss ja welche Felder für welches Formular ausgefüllt werden müssen.
Außerdem kontrolliert doch der Programmierer selber, welche Feldnamen er verwendet.
Unsinnige Diskussion also, m.E.
 
Zurück