molily: Wertepaare an Funktion übergeben und auswerten

Beitrag lesen

Hallo,

Würde das dann innerhalb meines php-Codes zu

<FORM ACTION="$PHP_SELF" METHOD=POST onSubmit="MeineFunktion({
'".$hallo."': '".$hi."',
'".$Antwort."': '".$42."',
});">


>   
> werden oder ist das syntaktisch falsch?  
  
Das lässt sich im Prinzip so »zusammenwurschteln«, aber schön ist das nicht. Ein paar allgemeine Anmerkungen:  
  
- HTML-Code wird hier in PHP-Code verschachtelt und es werden PHP-Strings mit HTML-Code zusammengebaut. Besser ist es, HTML-Code und PHP-Logik zu trennen und ein Template-System zu verwenden. Das nimmt einem viele Probleme ab und erzeugt lesbareren Code.  
  
- PHP-Variableninhalte aus der Datenbank werden unbehandelt in ein HTML-Attribut geschrieben. Fehlendes Escaping erzeugt Fehler und auch Sicherheitslücken. dedlfix hat einen Artikel zum Grundproblem geschrieben: [Kontextwechsel beachten](http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel).  
  
- JavaScript-Code wird in einem HTML-Attribut verschachtelt. Hier fehlt erneut das korrekte Escaping. Aber auch konzeptionell sollte das besser getrennt werden.  
  
Eine Möglichkeit, das zu verbessern, ist das Erzeugen eines [JavaScript-Moduls](http://molily.de/js/organisation-module.html#object-literal), das das Event-Handling aufsetzt.  
  
Die Objekt-Daten können JavaScript auf verschiedene Weise übergeben werden. Eine Möglichkeit ist, sie als [JSON](http://de.wikipedia.org/wiki/JavaScript_Object_Notation) zu serialisieren und in ein <script>-Element zu schreiben:  
  
~~~php
$key1 = 'foo'; $val1 = '1';  
$key1 = 'bar'; $val2 = '2';  
  
// Erzeuge einen PHP-Array:  
$arr = array();  
$arr[$key1] = $val1;  
$arr[$key2] = $val2;  
// Erzeuge einen JSON-String daraus:  
$json_string = json_encode($arr);  
// ergibt {"foo": 1, "bar": 2}  
// Bereite das JSON darauf vor, in ein script-Element geschrieben zu werden:  
$html_safe_json = str_replace('</', '<\\/', $json_string);  
// Das JSON kann nun </script> enthalten, ohne dass [link:http://de.wikipedia.org/wiki/Cross-Site-Scripting@title=Cross-Site-Scripting] möglich ist  

Der ausgelagerte JavaScript-Code:

<script>  
[code lang=javascript]var FormularLogik = {  
  init: function () {  
    // Event-Handling: Registriere submit-Handler beim Formular  
    document.getElementById('meinFormular').onsubmit = this.submitHandler;  
  },  
  submitHandler: function () {  
    // …  
  },  
  daten: <?php echo $html_safe_json; ?>  
};

FormularLogik.init();
</script>[/code]

Im JavaScript-Code steht dann letztlich daten: {"foo": 1, "bar": 2}.

Der Code geht davon aus, dass das form-Element die ID »meinFormular« besitzt und vorher im HTML-Code steht.

Eine weitere häufig verwendete Möglichkeit, JSON in HTML sicher unterzubringen, sind data-Attribute:

<form data-meine-daten="<?php echo $html_safe_json; ?>">

Das Escaping kann hier mit htmlspecialchars vorgenommen werden:

$html_safe_json = htmlspecialchars($json_string);

Ein Template-System nimmt einem so etwas ab.

Disclaimer 1: Es geht ums Prinzip. Obiger Code ist ungetestet. Wahrscheinlich habe ich nicht alle Angriffsvektoren bedacht.

Disclaimer 2: Ich programmiere schon seit 10 Jahren kein PHP mehr.

Mathias