Tobi: Wertepaare an Funktion übergeben und auswerten

Hallo,

bisher übergebe ich mit einem eventhandler an eine Funktion immer nur Variablen.
Und wenn die Variablen zum B. ein Wertepaar sind, gebe ich sie als "key_wert" weiter und splitte sie dann in der js funktion wieder.
Gibt es dazu auch einen anderen Weg, mehrere Wertepaare an eine Funktion weiter zu geben?
Thx, Tobi

  1. Tach!

    Gibt es dazu auch einen anderen Weg, mehrere Wertepaare an eine Funktion weiter zu geben?

    Mehrere Parameter, ein Array, ein Objekt.

    dedlfix.

    1. Mehrere Parameter, ein Array, ein Objekt.

      Objekt (so weit bin ich noch nicht)
      Array (ok, das schau ich mir gerne an)

      Nur, mehrere Parameter, was genau meinst Du damit?

      Hast Du dazu nen Link oder ein neutrales Beispiel?

      Tobi

      1. Tach!

        Nur, mehrere Parameter, was genau meinst Du damit?

        function foo(param1, param2, param3, ...) {...}

        dedlfix.

        1. function foo(param1, param2, param3, ...) {...}

          Ja, hab ich mir schon gedacht. Nur, wie "klamüser" ich das später wieder auseinander, sodaß daraus weider Wertepaare werden?

          Ich glaube, da sind doch Arrays vielleicht sinvoller? Kann man denn ein assoziatives Array in JS an eine Funktion weiter geben?

          Tobi

          1. Tach!

            function foo(param1, param2, param3, ...) {...}
            Ja, hab ich mir schon gedacht. Nur, wie "klamüser" ich das später wieder auseinander, sodaß daraus weider Wertepaare werden?

            Bei einem Array hast du Key und Wert. Bei zwei Variablen hast du Variable 1 und Variable 2. Da ist nichts grundsätzlich anders. Man hat am Ende zwei Dinge, die man weiterverarbeiten kann.

            Ich glaube, da sind doch Arrays vielleicht sinvoller? Kann man denn ein assoziatives Array in JS an eine Funktion weiter geben?

            Arrays sind "nur" eine Form der Zusammenfassung an einem Ort. Und ja, ein Array lässt sich genauso übergeben wie einfache Variablen und Werte. Übrigens ist ein assoziatives Array in Javascript in Wirklichkeit ein Objekt. Damit hast du deinen Einstieg in Objekte.

            dedlfix.

            1. Bei einem Array hast du Key und Wert. Bei zwei Variablen hast du Variable 1 und Variable 2. Da ist nichts grundsätzlich anders. Man hat am Ende zwei Dinge, die man weiterverarbeiten kann.

              Ich weiß nur vorher nicht, wieviele Parameter es werden. Das kann sehr unterschiedlich sein.

              Arrays sind "nur" eine Form der Zusammenfassung an einem Ort. Und ja, ein Array lässt sich genauso übergeben wie einfache Variablen und Werte. Übrigens ist ein assoziatives Array in Javascript in Wirklichkeit ein Objekt. Damit hast du deinen Einstieg in Objekte.

              Ich glaube, an dieser Stelle muß ich mir erstmal anschauen, wie das in der Praxis geht, bevor ich weiter "Löcher in die Luft" frage. ;)

              Tobi

              1. Tach!

                Bei einem Array hast du Key und Wert. Bei zwei Variablen hast du Variable 1 und Variable 2. Da ist nichts grundsätzlich anders. Man hat am Ende zwei Dinge, die man weiterverarbeiten kann.
                Ich weiß nur vorher nicht, wieviele Parameter es werden. Das kann sehr unterschiedlich sein.

                Dann ist ein übergebenes Array die bessere Wahl.

                Andererseits kann man auf die Parameter einer Funktion auch über das vordefinierte Array arguments zugreifen.

                dedlfix.

          2. [latex]Mae  govannen![/latex]

            Ja, hab ich mir schon gedacht. Nur, wie "klamüser" ich das später wieder auseinander, sodaß daraus weider Wertepaare werden?

            Ich glaube, da sind doch Arrays vielleicht sinvoller? Kann man denn ein assoziatives Array in JS an eine Funktion weiter geben?

            In Javascript gibt es keine assoziativen Arrays.

            Es ist zwar durchaus möglich, folgendes zu schreiben:

            var foo = []; // die veraltete Form wäre var foo = new Array()  
            foo['Hallo'] = 'hi';  
            foo['Antwort'] = 42;
            

            allerdings ist das Murks, weil die nativen Array-Methoden diese Werte entweder gar nicht oder nicht immer beachten (müßte ich nachschauen, aber da man sinnvollerweise so nicht programmiert, ist es eher akademisch)

            Besser ist, wie dedlfix schon schrieb, ein Objekt:

            var foo = {};  
            foo['Hallo'] = 'hi';  
            foo['Antwort'] = 42;
            

            oder übersichtlicher

            var foo = {  
                'Hallo': 'hi',  
                'Antwort': = 42  
            };
            

            Übergabe:

            meineFunktion(foo);

            Man kann die Parameter auch direkt im Funktionsaufruf definieren:

            meineFunktion({  
                'Hallo': 'hi',  
                'Antwort': = 42  
            });
            

            Zugriff in der Funktion dann mit foo.Hallo oder foo['Hallo']

            Stur lächeln und winken, Männer!

            Kai

            --
            Array(16).join("x" - 1) + " Batman!"
            „Die Borg würden nicht mal Spaß verstehen, wenn sie einen Vergnügungspark assimiliert hätten!” (B'Elanna Torres)
            SelfHTML-Forum-Stylesheet
            1. Hi Kai,

              sehr sehr hilfreiches Post, danke! (Bitte könnte das mal einer der Registrierten kennzeichnen?)

              Man kann die Parameter auch direkt im Funktionsaufruf definieren:

              meineFunktion({

              'Hallo': 'hi',
                  'Antwort': = 42
              });

              
              >   
                
                
              Würde das dann innerhalb meines php-Codes zu  
                
              ~~~php
                
              <FORM ACTION=\"$PHP_SELF\" METHOD=POST onSubmit=\"MeineFunktion({  
              '".$hallo."': '".$hi."',  
              '".$Antwort."': '".$42."',  
              });\">  
              
              

              werden oder ist das syntaktisch falsch?

              Wie funktioniert die Auswertung in der Funktion, also auch bei Zugriff auf den Key?

              So?

                
              function ArrayFunktion(schluessel) {  
              for (var elem in schluessel) {  
              document.write(elem + ":" + schluessel[elem] + "<br />");  
              }  
              
              

              Tobi

              1. oder ist das syntaktisch falsch?

                Das sieht erstmal ganz gut aus, am besten siehst du dir aber den generierten Code an, da sieht man es besser.

                Wie funktioniert die Auswertung in der Funktion, also auch bei Zugriff auf den Key?

                In der Regel kennt man ja die Objekteigenschaften und kann mit schluessel.eigenschaft darauf zugreifen.
                Wenn nicht, geht es so wie du es gemacht hast, mit einer for-in-Schleife.
                document.write zerstörrt aber dein document. Nutze besser innerHTML.

              2. [latex]Mae  govannen![/latex]

                Wie funktioniert die Auswertung in der Funktion, also auch bei Zugriff auf den Key?

                So?

                function ArrayFunktion(schluessel) {
                for (var elem in schluessel) {
                document.write(elem + ":" + schluessel[elem] + "<br />");
                }

                  
                Im Prinzip schon. Allerdings sehr unglücklich:  
                  
                  - „ArrayFunktion“ ist verwirrend, da überhaupt nicht mit Arrays sondern mit Objekten gearbeitet wird (daß Arrays im Prinzip auch eine spezielle Form von Objekten sind, ist hier nicht wichtig, da es dabei nur um Interna von Javascript geht).  
                  
                  - Es ist mehr oder weniger Konvention, daß nur Konstruktor-Funktionen mit einem Großbuchstaben beginnen  
                  
                  - das was du als „elem“ bezeichnest, ist in Wirklichkeit der Schlüssel (genauer gesagt der Eigenschaftsname [property name])  
                  
                  - das, was du als „schluessel“ bezeichnest ist das Objekt, hier steht es dir frei, selbiges mit einem passenden Namen zu versehen.  
                  
                  - document.write wäre nur für Funktionen zulässig, die ausschließlich vor der Fertigstellung des (HTML) Dokuments  aufgerufen würden, wenn es sich nicht um ein Beispiel handeln würde.  
                  
                Übrigens: In deinem PHP-Code steht $PHP\_SELF. Damit öffnest du eine schwerwiegende XSS-Sicherheitslücke, [wenn du es nicht kontextgerecht behandelst oder eine andere Servervariable verwendest](http://forum.de.selfhtml.org/archiv/2008/12/t180453/).  
                  
                Stur lächeln und winken, Männer!  
                  
                Kai  
                
                -- 
                `Array(16).join("x" - 1) + " Batman!"`{:.language-javascript}  
                I am Pentium of Borg. Division is futile. You will be approximated.  
                  
                [SelfHTML-Forum-Stylesheet](http://selfhtml.knrs.de/#h_stylesheet)  
                
                
              3. Tach!

                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?  
                  
                Du wirst kaum $42 als Variable haben, denn die wäre syntaktisch falsch. Ansonsten ist sicher auch noch wichtig, dass du Werte ein Javascript-Code einfügst, der in HTML steht. Das heißt, dass du hier zweimal einen Kontextwechsel berücksichtigen musst. Es sei denn, du kannst sicherstellen, dass du keine Zeichen mit Sonderbedeutung in beiden Kontexten verwendest.  
                  
                  
                dedlfix.
                
                1. Es sei denn, du kannst sicherstellen, dass du keine Zeichen mit Sonderbedeutung in beiden Kontexten verwendest.

                  Die Werte kommen 1:1 aus der db.

                  Tobi

                  1. Tach!

                    Es sei denn, du kannst sicherstellen, dass du keine Zeichen mit Sonderbedeutung in beiden Kontexten verwendest.
                    Die Werte kommen 1:1 aus der db.

                    Also kannst du es nicht sicherstellen. Ein DBMS wird ja nicht zum Ablegen konstanter Werte verwendet, sonst bräuchte man sie ja nicht. Man muss annehmen, dass der Inhalt Sonderzeichen enthalten kann. Man sollte das selbst dann annehmen, wenn man eigentlich sichergestellt hat, dass nur Werte ohne Sonderzeichen in die Datenbank geschrieben wurden. So eine Datenbank ist ja nicht soweit abgeschottet, dass nur der eine Prozess schreiben kann und unter keinen anderen Umständen Sonderzeichen hineingelangen können. Wie auch immer, es ist besser, davon auszugehen, dass in der Datenbank alles mögliche drinstehen kann und das bei der Ausgabe korrekt zu maskieren. Der geringe, kaum messbare Performanceverlust wiegt die potentiellen Sicherheitsprobleme bei weitem wieder auf.

                    Lange Rede, ... Für Javascript kennt PHP keine Maskierfunktion. Im Kontextwechsel-Artikel findest du jedoch eine in der Fortsetzung. Anschließend muss da noch htmlspecialchars() drumherum, weil das Javascript als Attributwert in HTML landet.

                    dedlfix.

                    1. Also kannst du es nicht sicherstellen. Ein DBMS wird ja nicht zum Ablegen konstanter Werte verwendet, sonst bräuchte man sie ja nicht.

                      Es geht um genau 2 Spalten und dort sind von mir persönlich hinterlegte konstante Werte drin. ;)

                      Tobi

                      P.S: Den Artikel zum Kontentwechsel kenne ich auswendig. :)

                      1. P.S: Den Artikel zum Kontentwechsel kenne ich auswendig. :)

                        Kontextwechsel meine ich natürlich.

                        Aber dieses Forum ist echt "tricky", ich habe beim absenden den Flüchtigkeitsfehler bemerkt und (gefühlt) ewig gebraucht, mein eigenes Posting wieder zu finden. Ziemlich userunfreundlich, sowas.

                        Tobi

                        1. Meine Herren,

                          Aber dieses Forum ist echt "tricky", ich habe beim absenden den Flüchtigkeitsfehler bemerkt und (gefühlt) ewig gebraucht, mein eigenes Posting wieder zu finden. Ziemlich userunfreundlich, sowas.

                          Das Forum ist für angemeldete Benutzer konfigurierbar wie kein zweites. User-Stylesheets, -Javascripts und Konfigurationen lassen fast keine Wünsche offen.

                          --
                          Hey Girl,
                          i wish you were asynchronous, so you'd give me a callback.
                          1. Tach!

                            Aber dieses Forum ist echt "tricky", ich habe beim absenden den Flüchtigkeitsfehler bemerkt und (gefühlt) ewig gebraucht, mein eigenes Posting wieder zu finden. Ziemlich userunfreundlich, sowas.
                            Das Forum ist für angemeldete Benutzer konfigurierbar wie kein zweites. User-Stylesheets, -Javascripts und Konfigurationen lassen fast keine Wünsche offen.

                            Und in dem Fall wäre Hervorhebung der eigenen Postings oder die Interessant-Markierung hilfreich.

                            dedlfix.

                            1. Und in dem Fall wäre Hervorhebung der eigenen Postings oder die Interessant-Markierung hilfreich.

                              Oder man nimmt die Suchfunktion des Browsers zu Hilfe ;)

                              MfG
                              bubble

                              --
                              If "god" had intended us to drink beer, he would have given us stomachs. - David Daye
                      2. Hallo,

                        P.S: Den Artikel zum Kontextwechsel kenne ich auswendig. :)

                        Auswendig kennen und verstanden haben sind zwei Paar Schuhe.
                        Das Anwenden ist dann das dritte Paar Stiefel...

                        Gruß
                        Kalk

              4. 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

                1. Tach!

                  // 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 Cross-Site-Scripting möglich ist

                  Ich hab grad nachgedacht, ob hier nicht auch htmlspecialchars() verwendet werden könnte. Aber die Antwort war dann noch nein. Und man muss erwähnen, dass $html_safe_json als Name nicht ganz stimmt. Er ist etwas zu allgemein. Javascript kann an zwei Arten von Orten im HTML stehen. Die eine Art ist als Attribut in einem HTML-Element, die andere innerhalb eines Script-Elements (<script>...</script>). Und bei denen sind die Regeln etwas anders. Im script-Block wird alles wörtlich an Javascript durchgereicht. Ein &lt; zum Beispiel würde als ebendiese vier Zeichen angesehen werden. Das erste Auftreten von </ allerdings lässt den Parser wieder in den HTML-Modus zurückschalten. Deswegen muss da nur ein eventuelles </ berücksichtigt und entschärft werden. Anders im Attribut, hier wird der Inhalt zuerst nach den HTML-Regeln aufgelöst und dann erst an Javascript weitergereicht. Hier muss htmlspecialchars() verwendet (gegebenenfalls mit ENT_QUOTES) und nicht nur </ beachtet werden.

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

                  Ich habe nichts zu beanstanden.

                  dedlfix.