Bei Klick PHP-Funktion aufrufen

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hi,
    ich habe mir eine eigen kleine Homepage geschrieben. Beim Klick auf ein Bild soll eine PHP-Funktion aufgerufen werden.
    Ich habe bislang zwei Ansätze verfolgt.
    Erste Idee: Ich habe in einer functions.php meine Funktionen verfasst.
    Zwei verschiedene. Dann habe ich in der index.html einen Link um das Bild gelegt mit dem href="functions.php?funct=1"

    Dann mit get abgefragt ob die Variable funct 1 oder 0 ist und dementsprechend die richtige Funktion aufgerufen. Das klappte erstens gar nicht und zweitens werde ich im Browser ja dann auf die "leere" functions.php umgeleitet. Das ist nicht so schön. Ich würde viel lieber auf der index.html bleiben. Es sollte im perfekten Fall nichts passieren, außer dass die php function ausgeführt wird.

    Zweite Idee: In der functions.php beide Funktionen definieren, dann die index.html in index.php umbenannt und im body die functions.php included. Jetzt sollte ich ja eigtl die Funktionen aufrufen können. Aber ich weiß gar nicht wie ich das nun umsetzen soll.
    Wie sage ich "wenn Klick auf Bild, dann php function".

    Kann mir jmd Tipps geben? Vielen Dank :)

  • Folgendes sollte relativ einfach zu verstehen sein:

    index.html[code=php]
    <!DOCTYPE html>
    <html>
    <head>
    <title>GPIO test</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jque…1/jquery.min.js"></script>
    <script type="text/javascript">
    function GPIO(pin){
    $('#result').load("runGPIO.php?pin="+pin);
    }
    </script>
    </head>
    <body>

    <button type="button" onclick="GPIO('15')" value="bla">GPIO 15</button>
    <p><div id="result"></div></p>

    </body>
    </html>
    [/php]

    runGPIO.php
    [code=php]<?php
    if (isset($_GET['pin'])) {
    echo "runGPIO pin: ".$_GET['pin']."<br/>\n";
    }
    ?>[/php]

  • Vielen Dank für deine schnelle und kompetente Antwort.

    Verstehen, ja.
    Auf mein Problem anwenden, leider nein.

    Wo liegt mein Fehler?

    Ich habe das Javascript-Script importiert und eine entsprechende Methode für meinen Fall geschrieben.

    index.html

    Code
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>  
        <script type="text/javascript">
            function schalten(how){
                $('#result').load("php/functions.php?how="+how);
            }
        </script>

    im body der index.html

    Code
    <div type="button" onclick="schalten('1')">
                            <img src="images/ein.png" style="height:100px; width:100px" alt=""/>
                        </div>

    functions.php
    [code=php]function schalten(x){
    shell_exec("sudo /opt/rcswitch-pi/sendRev D 2 " + x);
    }

    if (isset($_GET['how']) {
    schalten(how); [/php]

  • Die Javascript Funktion ist keine PHP Funktion. PHP wird auf dem Serverseite ausgeführt, Javascript auf der Clientseite.
    Du kannst die "schalten" Funktion in der functions.php auch xyz nennen, das spielt fürs Javascript absolut keine Rolle.

    Wie du an meinem Beispiel eigentlich sehen kannst, ruft die Javascript-Funktion eine PHP Datei über den Webserver auf und übergibt via GET eine Variable "pin" mit nem Wert.
    Du übergibst aber den Wert von $_GET['how'] gar nicht an deine PHP Funktion ...

    Davon abgesehen rate ich prinzipiell von shell_exec ab. Siehe dazu Forumsuche nach: sudo webscript


    PS: mit korrekten einrückungen sehen Scripts oft übersichtlicher aus.

  • Kann deinen Kommentar gerade nicht einordnen. Ich übergebe die Variable doch an meine PHP-Funktion?! Ich übergebe how an die functions.php. Dort nehme ich mir den Wert mittels GET und das how übergebe ich dann an "schalten". Oder wo ist der Syntaxfehler? Weil die Semantik müsste eigtl korrekt sein imho.

  • Nein, du prüfst nur ob bei $_GET eine Variable 'how' gesetzt ist, verwertest diese aber nicht weiter.

    $_GET ist ein Array. 'how' ist der Schlüssel und $_GET['how'] beinhaltet den Wert des Schlüssels

    Desweiteren ist das PHP nicht Python. " + x funktioniert hier also nicht, genauso wie du bei der Übergabe auch mit $x arbeiten musst, bereits oben beim deklarieren der function.

    Du machst:
    [code=php]
    function schalten(x){
    shell_exec("sudo /opt/rcswitch-pi/sendRev D 2 " + x);
    }

    if (isset($_GET['how']) {
    schalten(how);
    [/php]

    Richtiger wäre aber:
    [code=php]
    function schalten($x){
    shell_exec("sudo /opt/rcswitch-pi/sendRev D 2 " . $x);
    }

    if (isset($_GET['how'])) {
    schalten($_GET['how']);
    }
    [/php]und du hast auch das schließen der zweiten ( beim if vergessen..


    Schöner wäre allerdings:

    Spoiler anzeigen

    [code=php]<?php

    if (isset($_GET['how'])) { schalten($_GET['how']); }

    function schalten($x) {
    exec("sudo /opt/rcswitch-pi/sendRev D 2 " . $x, $output, $return_var);

    if (isset($return_var) AND $return_var >= 1) {
    echo "<font face='Arial, Helvetica, sans-serif' size='3' color='FF0000'>ERROR: </font>\n";
    echo "<font face='Arial, Helvetica, sans-serif' size='3' color='009900'>".exitcode($return_var)."<br/>\n";
    }
    if (isset($output) AND !empty($output)) {
    foreach($output AS $line) { echo $line."<br/>\n"; }
    }
    }

    function exitcode($code) {
    switch($code) {
    case 0: $ReturnCode = "Successful"; break;
    // case 1: $ReturnCode = "General Error (Miscellaneous errors, such as 'divide by zero' and other impermissible operations)";$
    case 1: $ReturnCode = "General Error (Miscellaneous errors, such as 'divide by zero' and other impermissible operations)"; break;
    case 2: $ReturnCode = "Incorrect Usage"; break;
    case 126: $ReturnCode = "Command found but not executable (Permission problem)"; break;
    case 127: $ReturnCode = "Command not found (Possible problem with \$PATH or a typo)"; break;
    case 128: $ReturnCode = "Invalid argument to exit (exit takes only integer args in the range 0 - 255)"; break;
    case 130: $ReturnCode = "Script terminated by Control-C"; break;
    default: $ReturnCode = $code;
    }
    return $ReturnCode;
    }

    ?>
    [/php]hier hast du dann nämlich auch eine Fehlerprüfung, falls der Befehl nicht erfolgreich war..


    Und mein letztes "PS" Kommentar bezieht sich auch auf deine index.html, der <script> Abschnitt wo du schalten() deklarierst ist kein Bestandteil der jquery.js und muss deshalb nicht eingerückt werden ;) Aber auch das </div> ist da etwas deplaziert, funktioniert zwar, sieht aber komisch aus und liest sich auch etwas umständlich

  • Vielen Dank nochmal für deine Antwort :)

    Also zum Einrücken: Im richtigen Script ist es korrekt eingerückt. Ist wohl beim Copy-Pasten passiert. Achte da eigtl auch relativ penibel drauf.

    Okay, klassische Anfängerfehler in PHP also. Ich muss gestehen, ich habe mit PHP bisher so gut wie gar nicht gearbeitet. Das mit dem Plus kenne ich aus Python, Java usw, ja. Und da du das in deinem Javascript-Part ebenso genutzt hattest, habe ich das ohne groß zu überlegen übernommen :D Einfach nur blöd.
    Also ist der . in PHP eine Art Komposition? Wie man ihn aus funktionalen Sprachen wie Haskell kennt?

    Sehr hübsch deine Lösung. Im privaten Umfeld verzichte ich nahezu immer auf das Abfangen von Fehlern. Sinnvoll ist das allerdings nicht, geb ich dir Recht. Reine Faulheit :P

    Nochmals vielen Dank, werde es nun nochmal testen.

    Es klappt leider nicht.

    Habe deinen PHP-Code übernommen und folgenden Javascript-Teil:

    Code
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>  
    <script type="text/javascript">
            function schalten(how){
               $('#result').load("php/functions.php?how="+how);
            } 
    </script>

    Methodenaufruf:

    Code
    <button style="border-radius:20px; border-color:black" type="button" onclick="schalten('1')">
           <img src="images/ein.png" style="height:100px; width:100px" alt=""/>
    </button>

    Einmal editiert, zuletzt von fuuman (4. Februar 2015 um 00:56)

  • Als ich das gestern nachgestellt habe hat es her problemlos funktioniert.

    Was passiert denn wenn du die functions.php manuell über deinen Browser aufrufst? Also: http://raspberry.ip/php/functions.php?how=1

    Kann es vielleicht sein das der Webserver kein Zugriff auf den php/ Ordner hat? Mit welchem Benutzer hast du den angelegt?

  • Naja aber der Webserver läuft über den Benutzer www-data. Wenn der dort keinen Zugriff hat kann er die functions.php auch nicht aufrufen. Deshalb solltest du das mal manuell aufrufen um auch ein Ausschlussverfahren zu machen; funktioniert die functions.php besteht wo anders ein Problem.

  • Manueller Aufruf bringt:

    Code
    pi@raspberrypi /var/www/own_shc/php $ php functions.php
    PHP Parse error:  syntax error, unexpected 'case' (T_CASE), expecting variable (T_VARIABLE) or '$' in /var/www/own_shc/php/functions.php on line 21

    Line21:

    Code
    21          case 2: $ReturnCode = "Incorrect Usage"; break;
  • Du solltest die functions.php über den Webbrowser aufrufen, nicht über shell/konsole!

    //EDIT: Ich hatte einen copy&past Fehler in der exitcode, da war eine Zeile abgeschnitten und ein $ am Ende der Zeile was da aber nicht hingehörte. Der Fehler war in Zeile 20. Korrekt sieht die function so aus:
    [code=php]
    function exitcode($code) {
    switch($code) {
    case 0: $ReturnCode = "Successful"; break;
    case 1: $ReturnCode = "General Error (Miscellaneous errors, such as 'divide by zero' and other impermissible operations)"; break;
    case 2: $ReturnCode = "Incorrect Usage"; break;
    case 126: $ReturnCode = "Command found but not executable (Permission problem)"; break;
    case 127: $ReturnCode = "Command not found (Possible problem with \$PATH or a typo)"; break;
    case 128: $ReturnCode = "Invalid argument to exit (exit takes only integer args in the range 0 - 255)"; break;
    case 130: $ReturnCode = "Script terminated by Control-C"; break;
    default: $ReturnCode = $code;
    }
    return $ReturnCode;
    }
    [/php]

  • Browser hatte ich schon manuell probiert, klappte ebenfalls nicht. Deswegen wollte ich schauen welche Ausgabe ich in der Konsole bekomme.

    Nach Korrigieren des CP-Fehlers: Okay, jetzt bekomme ich immerhin den Inhalt von $result im Browser angezeigt. Dort steht nun General Error: ..., also case 1.
    Jetzt muss ich nur noch rausfinden, wieso springt er in Fall 1..

    //edit: Also ich bin gerade etwas überfragt.
    Zugriffsrechte können es eigentlich nicht sein. Da der Error ja ausgegeben wird. Sprich Ausführung der Function, Rückgabe des Werts usw. funktionieren. Wenn die das Kommando aus der function in die Shell kopiere und ausführe klappt der Befehl.
    An der Übergabe des Parameters kann es auch nicht liegen. Ich übergebe die 1 für ein und die 0 für aus an die PHP-Function. Selbst wenn ich aber das " . $x" weglasse und einfach hart die "D 2 1" codiere, bekomme ich einen Gerenal Error.

    Und es ist ja auch korrekt, dass ich schalten('1') aufrufe, oder nicht?! 1 als String, so dass sie mit dem restlichen Befehl konkateniert werden kann.

    Also kA an welcher Stelle es da jetzt scheitert :( ..

    Einmal editiert, zuletzt von fuuman (5. Februar 2015 um 14:45)

  • Stimmt. Das hat auf jeden Fall dazu geführt, dass es gerade exakt einmal funktioniert hat. :D

    Wie mysteriös ist das denn nun wieder?^^

    Ich hatte visudo gerade angepasst, habe die Page neu geladen und auf EIN geklickt. Und die Funksteckdose wurde tatsächlich geschaltet. Allerdings klappte AUS dann nicht mehr. Dann "manuell" ausgeschaltet und auch EIN klappt nicht mehr. Der Befehl wird allerdings korrekt in $result angezeigt. Bei aus sendet er mit 0, bei ein mit der 1. Trotzdem tut sich an der Steckdose gar nichts mehr. Pi neustarten inkl. mal Strom komplett weg hat nichts gebracht.

    Letzte Idee ist jetzt die Steckdose mal kurz rausziehen. Manchmal hängen sich die Teile ja auch auf.

    Wenn es das nicht ist, ohje... :D

    //edit: Tatsache. Steckdose kurz raus. Und zack: ein, aus, ein, aus, ein, aus. Klappt.

    Ergo: Ich danke dir nochmals für deine Geduld und Mühe. :)

    Einmal editiert, zuletzt von fuuman (5. Februar 2015 um 15:42)

  • Ja, hab ich mir bereits angeschaut.

    Leider hab ich nun doch noch ein Problem. Gerade nochmal versucht - geht nicht mehr. Mit der normalen FB der Dosen klappt es aber.
    Liegt das vllt auch an der Verwendung von exec?

  • Nur zur Info (musste heute Mittag weg): Ich hatte das alles noch auf die Variante mit sudowebscript umgewandelt. Und jetzt klappt es tatsächlich jedes Mal. Heute Nachmittag und auch jetzt als ich wieder nach Hause kam bei jedem Klick, sehr zuverlässig.

    Wunderbar :)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!