Validierung per OOP/mehrdimensionale Arrays

Validierung per OOP/mehrdimensionale Arrays

am 13.10.2006 23:53:15 von Frank Huedelner

Hi Gruppe!

Ich habe auf einer Seite Formulare, die teilweise recht umfangreich sind
und verwende deshalb tlw. mehrdimensionale Arrays, um zusammengehörige
Werte logisch zusammenzufassen (um den Überblick zu behalten), oder
Array-Funktionen anwenden zu können. Beispiel: name="select[date]",
name="select[time]". Diese bekomme ich dann z.B. als
$_POST['select']['date']. Soweit, so gut.

Natürlich validiere ich die übergebenen Werte, dazu hab ich mir eine
Klasse gebaut. Alle validierten Werte kommen in ein eigenes Array,
nennen wir es $checked und zwar mit demselben Array-Key.
$_POST['select']['date'] wird also zu $checked['select']['date'] - um
den Überblick zu behalten. Nur auf dieses greife ich zu, wenn ich Daten
in Querys und dgl. einfülle, um Irrtümer auszuschließen. Das Problem
liegt darin, die Daten von $_POST, $_GET etc. in das andere Array zu
bekommen. Natürlich könnte ich für jede einzelne Variable schreiben:

if (isset($_POST['select']['date'])) {
$checked['select']['date'] = $check->add($_POST['select']['date']);
...
}

Das ist etwas langwierig. Lieber wäre mir ein

$list[] = array("['select']['date']");
$list[] = ...

foreach ($list as $item) {
$checked[$item[0]] = ...
}

Damit könnte ich eine Menge automatisieren. So wie oben beschrieben,
geht's natürlich nicht. Ich habe auch keine andere Möglichkeit gefunden,
auf x-dimensionale Arrays direkt zuzugreifen, wenn ihre Tiefe variabel
ist. Nicht mal die Verwendung von bösen[tm] variablen Varieblen à la

$temp = $checked['select']['date'];
$$temp = ...

funktioniert. Mit eindimensionalen Arrays wäre es einfach, aber leider
sind mehrdimensionale Arrays oft sehr praktisch.

Habt ihr Ideen? Ich hab extra die ganze Geschichte dazugeschrieben, um
evtl. auch Hinweise zu bekommen, falls es am Design an sich liegt. Ich
hab bis jetzt nämlich noch nicht viel im Netz zum Thema Validierung von
Variablen (nicht nur Formulare) mit OOP gefunden. Vielleicht könnt ihr
mir ja helfen.

Besten Dank,

Frank

Re: Validierung per OOP/mehrdimensionale Arrays

am 14.10.2006 06:37:50 von Jens Riedel

Frank Huedelner wrote:
....

> Ich habe auch keine andere Möglichkeit gefunden,
> auf x-dimensionale Arrays direkt zuzugreifen, wenn ihre Tiefe variabel
> ist.

Wenn du durch alle egal wie tief verschachtelten Werte des Arrays laufen
willst, musst du dies rekursiv tun.
Leider verschluckt 'array_walk_recursive()' dabei Schlüssel, sonst wäre
das ein Kandidat gewesen (falls du PHP5 verwendest).
Also würde ich mir an deiner Stelle eine rekursive Funktion bauen, die
das Array durchläuft, sich dabei aber für jedes Element die komplette
Schlüsselkette (also quasi den Pfad des Elements) merkt.
Alle damit gefundenen Elemente schiebst du dann mit deiner
$check->add()-Methode rüber in dein $checked-Array (dabei kannst du z.B.
noch auf bestimmte Schlüssel filtern, falls das nötig sein sollte).

> Habt ihr Ideen? Ich hab extra die ganze Geschichte dazugeschrieben, um
> evtl. auch Hinweise zu bekommen, falls es am Design an sich liegt.

Ich frage mich, warum du erstmal alle Werte aus $_POST/$_GET nach
$checked kopierst und alles durch deinen $check-Filter jagst.
Warum machst du es nicht so, dass du Variablen direkt aus $_POST
verwendest und erst bei der Verwendung selber checkst? Da hast du sie ja
direkt im Zugriff.

Also nach dem Prinzip:

$sql = "select * from table1 where user = '" .
$check->checkString($_POST['select']['username'] . "'");

Wenn das an sehr vielen Stellen vorkommt, sparst du dir natürlich
Schreibarbeit, wenn du dir wie momentan deine bereits geprüfte
Array-Kopie erstellst.
Die Einzel-Prüfung dagegen erlaubt dir eine variablere Prüfung, du
könntest z.B. Variablen, bei denen zu eine Zahl erwartest, anders prüfen
als Zeichenketten.

Gruß,
Jens


--
Der Kluegere gibt nach - Eine traurige Wahrheit:
sie begruendet die Weltherrschaft der Dummen.
- Marie von Ebner-Eschenbach

Re: Validierung per OOP/mehrdimensionale Arrays

am 14.10.2006 08:50:32 von Frank Huedelner

Jens Riedel schrieb:
> Frank Huedelner wrote:

Danke für Deine Antwort, Jens!

>> Ich habe auch keine andere Möglichkeit gefunden, auf x-dimensionale
>> Arrays direkt zuzugreifen, wenn ihre Tiefe variabel ist.
> Wenn du durch alle egal wie tief verschachtelten Werte des Arrays laufen
> willst, musst du dies rekursiv tun.
> Leider verschluckt 'array_walk_recursive()' dabei Schlüssel, sonst wäre
> das ein Kandidat gewesen (falls du PHP5 verwendest).

Nein, bin leider auf PHP4 als kleinsten gemeinsamen Nenner angewiesen,
momentan.

> Also würde ich mir an deiner Stelle eine rekursive Funktion bauen, die
> das Array durchläuft, sich dabei aber für jedes Element die komplette
> Schlüsselkette (also quasi den Pfad des Elements) merkt.
> Alle damit gefundenen Elemente schiebst du dann mit deiner
> $check->add()-Methode rüber in dein $checked-Array (dabei kannst du z.B.
> noch auf bestimmte Schlüssel filtern, falls das nötig sein sollte).

Ja, das wäre eine Möglichkeit. Allerdings hab ich ja den Schlüssel
schon, das ist ja nicht das Problem. Ein Element mit diesem Schlüssel zu
erzeugen ginge auch noch irgendwie, indem man

$checked = array($var1=>array($var2=>'Wert'));

macht. Wenn ich allerdings auf den Wert im $_POST-Array zugreifen will,
muss ich jedes Mal durch das ganze Array laufen und jeden Schlüssel
überprüfen. Das ist zu aufwändig. Da mach ich es lieber anders, indem
ich z.B. die Schlüssel in HTML anders definiere, sodass sie kein Array
ergeben (z.B. name="select.date"). Damit hab ich dann nur ein
eindimensionales $_POST-Array, mit dem ich vernünftig arbeiten kann und
schreib erst ganz am Ende die Daten in das mehrdimensionales
$checked-Array. Auch irgendwie krumm...

>> Habt ihr Ideen? Ich hab extra die ganze Geschichte dazugeschrieben, um
>> evtl. auch Hinweise zu bekommen, falls es am Design an sich liegt.
> Ich frage mich, warum du erstmal alle Werte aus $_POST/$_GET nach
> $checked kopierst und alles durch deinen $check-Filter jagst.
> Warum machst du es nicht so, dass du Variablen direkt aus $_POST
> verwendest und erst bei der Verwendung selber checkst? Da hast du sie ja
> direkt im Zugriff.
[...]
> Wenn das an sehr vielen Stellen vorkommt, sparst du dir natürlich
> Schreibarbeit, wenn du dir wie momentan deine bereits geprüfte
> Array-Kopie erstellst.

Das tut es. Auch wenn es nur drei Stellen sind, muss ich jedes Mal daran
denken und ggf. drei Mal dieselbe Variable validieren. Deshalb die Idee,
alle Variablen, die verwendet werden, gleich am Anfang prüfen und in
einem Array zur Verfügung stellen, wo ich bequem und ohne mir Gedanken
machen zu müssen, darauf zugreifen kann, ob für Formular-Werte oder
Query-Werte.

> Die Einzel-Prüfung dagegen erlaubt dir eine variablere Prüfung, du
> könntest z.B. Variablen, bei denen zu eine Zahl erwartest, anders prüfen
> als Zeichenketten.

Das kann ich sowieso. Deswegen mache ich es gleich am Anfang, weil die
Funktion $check ja nicht weiß, um welchen Wert es sich handelt. Sonst
wäre es ja einfach: Einfach $check auf jeden Wert im $_POST-Array
loslassen und fertig. So aber mache ich es so:

$checked['select']['date'] = new Check_date;
// Parameter setzen (gültiger Bereich, Format, ...)

Und ab dann brauch ich nur mehr den Wert zu übergeben und das Objekt
kümmert sich um alles: Wert prüfen, Wert setzen, Fehlerbehandlung, ...

Frank

Re: Validierung per OOP/mehrdimensionale Arrays

am 14.10.2006 11:07:29 von muck

Frank Huedelner schrieb:

> Hi Gruppe!
>
> Ich habe auf einer Seite Formulare, die teilweise recht umfangreich sind

Formulare oder Formular? Submit sendet ja für gewöhnlich nur ein
Formular

>
> Habt ihr Ideen? Ich hab extra die ganze Geschichte dazugeschrieben, um
> evtl. auch Hinweise zu bekommen, falls es am Design an sich liegt. Ich
> hab bis jetzt nämlich noch nicht viel im Netz zum Thema Validierung von
> Variablen (nicht nur Formulare) mit OOP gefunden. Vielleicht könnt ihr
> mir ja helfen.
>

Wenn du objektorientiert meinst: Versuchs mal mit einer
Datenhaltungsklasse, das ist immer ein sauberes Design, man blickt da
ganz gut durch, so in diesem Stile:
(php4)

class Person {

var $vorname=3D"";
var $nachname=3D"";
var $geprüft=3D"";

function Person ($vorname, $nachname)
{
$this->vorname=3D$vorname;
$this->nachname=3D$nachname;
$this->geprüft=3D0;
}

und jetzt entsprechende get- und set-Funktionen drunter usw.:

function set_vorname($vorname)
{
$this->vorname=3D$vorname;
}

function get_vorname()
{
return $this->vorname;
}

nun könnte man auch noch die check-Funktionen reinballern

function check_vorname()
{
if($this->vorname!=3D"") // nur so als Beispiel
{
$this->geprüft=3D1;
}
}
}

Vielleicht hilft dir solch ein Ansatz den Überblick zu behalten.

MfG

Markus

Re: Validierung per OOP/mehrdimensionale Arrays

am 14.10.2006 12:29:37 von Claus Reibenstein

Frank Huedelner schrieb:

> $_POST['select']['date'] wird also zu $checked['select']['date'] - um
> den Überblick zu behalten. Nur auf dieses greife ich zu, wenn ich Daten
> in Querys und dgl. einfülle, um Irrtümer auszuschließen. Das Problem
> liegt darin, die Daten von $_POST, $_GET etc. in das andere Array zu
> bekommen.

$checked = array_merge($_POST, $_GET, ...);

Gruß. Claus

Re: Validierung per OOP/mehrdimensionale Arrays

am 15.10.2006 00:12:28 von Frank Huedelner

Markus schrieb:
> Frank Huedelner schrieb:

>> Ich habe auf einer Seite Formulare, die teilweise recht umfangreich sind
> Formulare oder Formular? Submit sendet ja für gewöhnlich nur ein
> Formular

Es sind manchmal mehrere, was ja aber auch keinen Unterschied macht.

>> Habt ihr Ideen? Ich hab extra die ganze Geschichte dazugeschrieben, um
>> evtl. auch Hinweise zu bekommen, falls es am Design an sich liegt. Ich
>> hab bis jetzt nämlich noch nicht viel im Netz zum Thema Validierung von
>> Variablen (nicht nur Formulare) mit OOP gefunden. Vielleicht könnt ihr
>> mir ja helfen.
> Wenn du objektorientiert meinst: Versuchs mal mit einer
> Datenhaltungsklasse, das ist immer ein sauberes Design, man blickt da

Die Idee ist ja an sich nicht schlecht, wenn es sich um zusammengehörige
Daten handelt. Leider habe ich mehrere Seiten, auf denen in Formulare
tlw. sehr verschiedene Daten zu verschiedenen Zwecken verarbeitet werden.

Ich versuch, das Problem zu destillieren:

Wie validiere ich möglichst automatisch Daten, die in einem
n-dimensionalen Array vorliegen, wobei n > 1?

Danke für Eure Mühe,

Frank

Re: Validierung per OOP/mehrdimensionale Arrays

am 15.10.2006 00:15:34 von Frank Huedelner

Claus Reibenstein schrieb:
> Frank Huedelner schrieb:

>> $_POST['select']['date'] wird also zu $checked['select']['date'] - um
>> den Überblick zu behalten. Nur auf dieses greife ich zu, wenn ich Daten
>> in Querys und dgl. einfülle, um Irrtümer auszuschließen. Das Problem
>> liegt darin, die Daten von $_POST, $_GET etc. in das andere Array zu
>> bekommen.
>
> $checked = array_merge($_POST, $_GET, ...);

Damit hätt ich zwar alle Daten drüben, bringt mich aber auch nicht
weiter. Ich hab mein Problem in meiner Antwort auf Markus Posting
nochmal zusammengefasst. Vielleicht fällt Dir dazu ja noch was ein.

Schönen Abend,

Frank

Re: Validierung per OOP/mehrdimensionale Arrays

am 15.10.2006 03:40:18 von Niels Braczek

Frank Huedelner schrieb:

> Wie validiere ich möglichst automatisch Daten, die in einem=20
> n-dimensionalen Array vorliegen, wobei n > 1?

Gegen welche Definition?

MfG
Niels

--=20
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------

Re: Validierung per OOP/mehrdimensionale Arrays

am 15.10.2006 09:33:40 von Frank Huedelner

Niels Braczek schrieb:
> Frank Huedelner schrieb:

>> Wie validiere ich möglichst automatisch Daten, die in einem
>> n-dimensionalen Array vorliegen, wobei n > 1?
> Gegen welche Definition?

Die Definition variiert je nach erwartetem Datentyp und Inhalt und muss
demnach für jedes einzelne Element definiert werden können.

Grüße,

David

Re: Validierung per OOP/mehrdimensionale Arrays

am 15.10.2006 14:32:16 von gandolph

Frank Huedelner schrieb:
> Niels Braczek schrieb:
>> Frank Huedelner schrieb:
>
>>> Wie validiere ich möglichst automatisch Daten, die in einem
>>> n-dimensionalen Array vorliegen, wobei n > 1?
>> Gegen welche Definition?
>
> Die Definition variiert je nach erwartetem Datentyp und Inhalt und muss
> demnach für jedes einzelne Element definiert werden können.
>
> Grüße,
>
> David

mh, ich wuerd das grob so machen:

#Startbedingungen
$abbruch = false;
$temp = "_POST";
$aSchluessel[] = NULL;

while($abbruch == false)
{

$temp_info = each($$temp);

count($$temp) > 1 ? $aSchluessel[] = $temp_info[key];


# daten aus $$temp in neues array schreiben, schlüssel steht im
# $temp_info.
# daten aus $$temp loeschen, sofern count($$temp) == 1 (per unset ($$temp))

if ((count ($_POST) == 1) && (count($$temp == 1))
$abbruch == true;

$temp = "_POST".end($aSchluessel);
}


ich hoff, die idee kommt rueber, und ich hab mit der Übergabe des
aktuellen Keys ned zu viel mist gebaut... wie du das genau umsetzt musst
du selber rausfinden, weil erstens hab ich jetzt kopfweh (da waren im
ersten entwurf variable variable Variablen (TM) drin - sprich $$$temp,
und DAS is dann horror pur...)

Re: Validierung per OOP/mehrdimensionale Arrays

am 15.10.2006 14:33:35 von gandolph

Frank Huedelner schrieb:
> Niels Braczek schrieb:
>> Frank Huedelner schrieb:
>
>>> Wie validiere ich möglichst automatisch Daten, die in einem
n-dimensionalen Array vorliegen, wobei n > 1?
>> Gegen welche Definition?
>
> Die Definition variiert je nach erwartetem Datentyp und Inhalt und
muss demnach für jedes einzelne Element definiert werden können.
>
> Grüße,
>
> David

mh, ich wuerd das grob so machen:

#Startbedingungen
$abbruch = false;
$temp = "_POST";
$aSchluessel[] = NULL;

while($abbruch == false)
{

$temp_info = each($$temp);

count($$temp) > 1 ? $aSchluessel[] = $temp_info[key];


# daten aus $$temp in neues array schreiben, schlüssel steht im
# $temp_info.
# daten aus $$temp loeschen, sofern count($$temp) == 1 (per unset
($$temp))

if ((count ($_POST) == 1) && (count($$temp == 1))
$abbruch == true;

$temp = "_POST".end($aSchluessel);
}


ich hoff, die idee kommt rueber, und ich hab mit der Übergabe des
aktuellen Keys ned zu viel mist gebaut... wie du das genau umsetzt musst
du selber rausfinden, weil erstens hab ich jetzt kopfweh (da waren im
ersten entwurf variable variable Variablen (TM) drin - sprich $$$temp,
und DAS is dann horror pur...) und zweitens kenn ich deine variablen
nicht gut genug um das zu testen...