dedlfix: PHP Update

Beitrag lesen

Tach!

$result = [
  'errors' => [
     ['name' => 'feld1', 'messages' => ['meldung11', 'meldung12']],
     ['name' => 'feld2', 'messages' => ['meldung21', 'meldung22']],
  ],
  'anderes_zeug' => ...
];

echo json_encode($result);

Ich verstehe z.B. schon mal nicht, was du mit den ganzen Felder meinst, Warum muss das alles so kompliziert und umständlich sein und wie könnte ich diese mit meinem Beispiel füllen?

Das ist so "kompliziert und umständlich", damit es einerseits die fachlichen Anforderungen erfüllt und andererseits an anderer Stelle sehr leicht zu handhaben ist. Ich baue diese verschachtelte Struktur in der Variable $result zusammen, damit ich diese mit einem einzigen json_encode() versandsicher verpacken kann und damit sie auf der Empfängerseite ordnungsgemäß gelesen und weiterverarbeitet werden kann.

Das 'anderes_zeug' ersetze ich mal durch 'status' und dann sieht das Ergebnis nach dem json_encode() wie folgt aus:

{
    "errors": [
        {
            "name": "feld1",
            "messages": [
                "meldung11",
                "meldung12"
            ]
        },
        {
            "name": "feld2",
            "messages": [
                "meldung21",
                "meldung22"
            ]
        }
    ],
    "status": "failed"
}

Das ergibt dann nach dem Auspacken durch jQuery ein Objekt mit den beiden Eigenschaften errors und status. status kannst du auslesen, um zu erkenenn, ob es Fehler gab oder nicht. Andererseits kann man das auch weglassen und schauen, ob errors leer oder gefüllt ist. errors ist ein Array, das für jedes (fehlerhafte) Feld einen Eintrag hat. Durch dieses Array kann man laufen den Namen des Feldes daraus lesen und die zugehörigen Meldungen. Damit kann man dann zum Feld gehen und machen, was immer man machen will.

Ich habe zwei Meldungen als Beispiel genommen. Vielleicht brauchst du in deinem Fall nur eine, wenn du nur auf "ist nicht leer" prüfen möchtest. Die Erfahrung zeigt aber, dass es oftmals nicht bei einer solchen einfachen Prüfung bleibt und man mehrere Kriterien auswerten muss. Die erzeugen dann auch mehrere potentielle Meldungstexte.

Warum reicht es nicht einfach so

if($_POST['ansprechpartner'] == ''){exit ("ctrl_20");}
if($_POST['email'] == ''){exit ("ctrl_21");}
if($_POST['nachricht'] == ''){exit ("ctrl_25");}

Weil im Fehlerfall das erste exit deine Auswertung beendet. Damit kannst du dem Anwender das entsprechende Feld markieren, aber ein Meldungstext ist nicht dabei. Falls er erraten hat, was falsch sein könnte, kann er den Feldinhalt dann auch korrigieren, nur um beim zweiten Absenden an einem anderen Feld hängenzubleiben. Er muss unter Umständen für jeden einzelnen Fehler eine Extra-Runde drehen. Mit meiner Struktur können alle Fehler auf einmal ermittelt und im Paket zur Verbesserung vorgelegt werden. Diese Struktur soll nicht mit einer einzigen Anweisung zusammengebaut werden, der Code sollte nur zeigen, wie sie am Ende aussehen muss. Vielmehr wird jeder Fehler durch deine Prüfungen einzeln festgestellt und die Struktur Stück für Stück ergänzt.

$.ajax({
  type: "POST",
  url: "senden.php",
  data: { ... },
  dataType: 'json',
}).done(function (result) {
  console.log('alles auf einmal:');
  console.log(result);

  console.log('die fehler einzeln:');
  result.errors.forEach(function (item) {
    console.log(item.name);
    item.messages.forEach(function (message) {
      console.log(message);
    });
  });
}).fail(function (xhr, status, error) {
  // was auch immer
  console.log(status);
  console.log(error);
});

Bei deinem data: { ... }, kommt wahrscheinlich mein var data = form.serialize(); also in diesem Fall data: data, den Rest von deinem Code verstehe ich nicht und schon gar nicht verstehe ich, wie ich diesen in meinen Code intergrieren soll

Der Rest vom Code wird ausgeführt, wenn der Ajax-Call fertig ist. Der done-Teil im Gut-Fall, der fail-Teil, wenn das Ajax den Server nicht kontaktieren konnte. Dass done und fail hinter der ajax-Methode hängen und nicht wie url oder data oder success übergeben wurden, ist lediglich eine andere Art und Weise, wie jQuery den Umgang mit diesen Handlern ermöglicht. Den fail-Teil kannst du weglassen, aber dann passiert nichts im Falle eines Fehler. Der Nutzer bekommt dann aber keine Reaktion und weiß nicht, dass sein Kontaktversuch misslungen ist. Das ist nicht besonders anwenderfreundlich. Man muss eigentlich immer mit Fehlern rechnen und sich überlegen, was man in dem Fall tun möchte. Und ja, das kann ein Programm um ein Vielfaches verlängern, als wenn man nur von bestem Kaiserwetter ausgeht. Die Funktion in done() ist das was du über den Parameter success übergeben hattest, beziehungsweise nach deinem Umstieg auf $.post() als dessen dritter Parameter.

In result jedenfalls steht die oben gezeigte Struktur, so wie sie mit PHP erstellt wurde, aber quasi übersetzt in Javascript-Objekt/Array, denn jQuery hat das, was ich mit json_encode() eingepackt habe, bereits wieder ausgepackt. Die console.log()-Ausgaben sollten zeigen, wie man auf die Einzelteile zugreifen kann. Mit der Zeile

result.errors.forEach(function (item) {

laufe ich über das Array mit den Fehlermeldungen. Für jedes (fehlerhafte) Eingabefeld wird die Funktion aufgerufen und in item steht der Datensatz zu einem Feld. In item.name ist der Feldname zu finden, in item.messages ein weiteres Array mit den Meldungstexten (wenn es mehrere Fehler gegeben hat). Die Meldungen könntest du in der Nähe der Felder anzeigen lassen.

Eine radikale Vereinfachung wäre, wenn du die Fehlermeldungstexte alle nacheinander in einen einzelnen String hängen würdest. Dann hast du sozusagen einen Roman, den du ohne weiteres so wie deine bisherige success-Message übertragen kannst. Und den kannst du zum Beispiel über oder unter dem Formular anzeigen. Nur ist das nicht besonders anwenderfreundlich, weil der sich dann selbst zusammensuchen muss, zu welchem Feld nun welcher Teil des Meldungsromans gehört. Mit diesem Roman weißt auch du nicht, auf welche Felder er sich bezieht und kannst diese nicht markieren. Deswegen ist meine Lösung eine "komplizierte und umständliche" Struktur, damit man alle benötigten Daten transportieren kann, um dem Anwender die bestmögliche Lösung bieten zu können und nicht er "kompliziert und umständlich" vorgehen muss, um das Formular abschicken zu können.

dedlfix.