Meike: String als Funktion ausführen

Hallo,
Ich möchte einen String als Funktion ausführen.
Das klappt auch, nur bin ich nicht sicher ob das so sein
darf, daher frage ich euch.

$x = 'abcdefgh';
$func = 'strtoupper';
$y = $func($x);
echo $y;

ich nehme also die Variable $func und setze ($x) einfach dran.
Ohne Punkt oder sonstwas und sie wird tatsächlich ausgeführt.

Hatt mich schon darauf eingestellt eval nutzen zu müssen,
aber wenn so geht, perfekt. Aber ist das richtig?
Und wenn Ja, wie kommt das, dass PHP das so begreift?

oder gibt es eine bessere Lösung?

vg.
Meike

  1. Hallo,

    $x = 'abcdefgh';
    $func = 'strtoupper';
    $y = $func($x);
    echo $y;

    ... Aber ist das richtig?

    ja http://www.php.net/manual/de/language.variables.variable.php

    Und wenn Ja, wie kommt das, dass PHP das so begreift?

    Es wurde so implementiert.

    oder gibt es eine bessere Lösung?

    Nein, nur eine andere Lösung: http://de3.php.net/manual/de/function.call-user-func.php

    Gruß aus Berlin!
    eddi

    1. Hallo Eddi,

      oder gibt es eine bessere Lösung?

      Nein, nur eine andere Lösung: http://de3.php.net/manual/de/function.call-user-func.php

      Wofür soll das gut sein, sehe da noch keinen Verwendungszweck?
      Aber muss ja einen Sinn haben sonst gäbe es das nicht.

      function friseur ($type) {
          print "Sie möchten einen $type-Kopf, kein Problem<br>";
      }
      call_user_func ('friseur', "Bubi");
      call_user_func ('friseur', "Pilz");

      Warum also nicht gleich:
      friseur('Bubi');
      friseur('Pilz');

      Meike

      1. Tach.

        function friseur ($type) {
            print "Sie möchten einen $type-Kopf, kein Problem<br>";
        }
        call_user_func ('friseur', "Bubi");
        call_user_func ('friseur', "Pilz");

        Warum also nicht gleich:
        friseur('Bubi');
        friseur('Pilz');

        Aus dem gleichen Grund, weshalb du nicht einfach $y = strtoupper($x) schreibst, nehme ich an.

        --
        Once is a mistake, twice is jazz.
      2. Hello,

        Warum also nicht gleich:
        friseur('Bubi');
        friseur('Pilz');

        function friseur ($type)

        {

        print "Sie möchten einen $type-Kopf, kein Problem<br>";
        }

        function noergler ($type)
          {
            echo "Ihre neue $type-Kopf-Frisur sieht Scheiße aus,<br>".
                 "aber kein Problem, ich hab nen Rasierer<br>";
          }

        $positiv = 'friseur';
        $negativ = 'noergler';

        echo "<hr>\n";

        call_user_function ($positiv($kopftyp));

        echo "<hr>\n";

        call_user_function ($negativ($kopftyp));

        echo "<hr>\n";

        Das Ganze ist rudimentäre OOP...

        Harzliche Grüße vom Berg
        http://www.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau

        1. Hello,

          Sorry, ist mal wieder was versickert.

          Indirekte Aufrufe dienen der Transformation
          Das ist die Voraussetzung für die Programmierung eines Programms
          sozusagen von Neumann in PHP

          Das Ganze ist rudimentäre OOP...

          Harzliche Grüße vom Berg
          http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau

        2. Hallo Tom,

          auch auf die Gefahr hin, dass ich nerve,
          ich verstehs trotzdem nicht. OOP ist klar, arbeite auch gern mit
          Klassen, aber dennoch versteh ich das hier nicht, denn:
          anstatt:

          $positiv = 'friseur';
          $negativ = 'noergler';

          call_user_function ($positiv($kopftyp));
          call_user_function ($negativ($kopftyp));

          geht doch auch schlicht:

          friseur($kopftyp);
          noergler($kopftyp);

          Meike
          ps. Deine Scriptseite ist interessant. Schade, dass nicht mehr
          Beispielscripte drin sind, würde öfter mal reinschauen ;-)

          1. Hello,

            auch auf die Gefahr hin, dass ich nerve,
            ich verstehs trotzdem nicht. OOP ist klar, arbeite auch gern mit
            Klassen, aber dennoch versteh ich das hier nicht, denn:
            anstatt:

            $positiv = 'friseur';
            $negativ = 'noergler';

            call_user_function ($positiv($kopftyp));
            call_user_function ($negativ($kopftyp));

            geht doch auch schlicht:

            friseur($kopftyp);
            noergler($kopftyp);

            Wenn Du nun eine externe Datei mit den Befehlen (und den Werten) hättest

            friseur nörgler nörgler nörgler friseur

            dann könntest Du die dem Script zuleiten und ausführen lassen.
            Befehle, die nicht bekannt sind, können nicht ausgeführt werden.

            Vergleichbar wäre nur eine include()-Datei mit den realen Funktionen.
            Die würde aber immer dazu führen, dass auch die realen Funktionen aufgerufen werden.
            (wollen wir mal hoffen, dass es sie gibt und niemand Blödsinn macht)
            Es fehlt eine Transformationsschicht, in der Du nach Belieben festlegen kannst, dass ab sofort

            grün zu Stuhl wird
              Tisch zu Haus
              Bett zu safen
              usw.

            Es sind nicht mur lineare Transformation möglch, sondern auch solche mit Abbildungsleichung.
            Auch datengesteuerte...

            Harzliche Grüße vom Berg
            http://www.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau

          2. echo $begrüßung;

            anstatt:

            $positiv = 'friseur';
            call_user_function ($positiv($kopftyp));
            geht doch auch schlicht:
            friseur($kopftyp);

            In dem einfachen Beispiel, ja. Wenn du aber eine Methode einer Klasse aufrufen willst, benötigst du call_user_func(), weil ein solcher callback [*] als array($object, 'methode') zu notieren ist, und der lässt sich nicht als variable function aufrufen lässt ("Fatal error: Function name must be a string").
            Auch kann man mit der Notation $func($var) nur eine festgelegte Anzahl Parameter übergeben. Möchte man eine flexible Parameteranzahl übergeben lässt sich das mit call_user_func_array() bewerkstelligen.

            [*] Callbacks sind übrigens ein Anwendungsfall für variable functions.

            echo "$verabschiedung $name";

      3. Re:

        http://de3.php.net/manual/de/function.call-user-func.php
        Wofür soll das gut sein, sehe da noch keinen Verwendungszweck?
        Aber muss ja einen Sinn haben sonst gäbe es das nicht.

        function friseur ($type) {
            print "Sie möchten einen $type-Kopf, kein Problem<br>";
        }
        call_user_func ('friseur', "Bubi");
        call_user_func ('friseur', "Pilz");

        Warum also nicht gleich:
        friseur('Bubi');
        friseur('Pilz');

        Für die Programmierung von komplexeren Anwendungen bin ich sehr dankbar, daß es diese Möglichkeit gibt und ich greife auch immer wieder darauf zurück. Ein vielleicht nachvollziehbares Fallbeispiel:

        Ein Programm wie ein Server oder eine GUI-Anwendung (beide lassen sich hervorragend mit PHP realisieren) bekommt zur Laufzeit einen Interrupt und muß abhängig davon, welche Art die Unterbrechung ist, darauf unterschiedlich reagieren. Du als Programmierer hast nun die Möglichkeit mit Kontrollstruktur zu arbeiten oder oder gleich mit Variablen ;)

          
        <?php  
        declare(ticks = 1);  
        function sig_handler($signo){  
             #Kontrollstruktur  
             switch ($signo) {  
                 case SIGTERM:  
                     sig_term();  
                     break;  
                 case SIGHUP:  
                     sig_hup();  
                     break;  
                 case SIGUSR1:  
                     sig_usr();  
                     break;  
                 default:  
                     exit(1);  
             }  
        }  
        pcntl_signal(SIGTERM, "sig_handler");  
        pcntl_signal(SIGHUP,  "sig_handler");  
        pcntl_signal(SIGUSR1, "sig_handler");  
        ?>  
        <?php  
        declare(ticks = 1);  
        function sig_handler($signo){  
             #Variable  
             $a=(SIGTERM=>'sig_term',  
                 SIGHUP =>'sig_hup',  
                 SIGUSR1=>'sig_usr'  
                );  
             @call_user_func($a[$signo]) || exit(1);  
        }  
        pcntl_signal(SIGTERM, "sig_handler");  
        pcntl_signal(SIGHUP,  "sig_handler");  
        pcntl_signal(SIGUSR1, "sig_handler");  
        ?>  
        
        

        Beides ist möglich, aber wenn Du auf mehr als 3 verschiedene Inerrupts achent sollst, dann wird das ganze auch schnell unübersichtlich. (Hinzukommt, daß diese  Methodik auch schneller abgearbeitet wird, als die Abarbeitung von Kontrollstrukturen.)

        Gruß aus Berlin!
        eddi

  2. Zu früh gefreut, leider.

    $x = 'abcdefgh';
    $func = 'strtoupper';
    $y = $func($x);
    echo $y;

    Wichtig ist für mich die Parameterübergabe, die
    kann ich nicht im Vorfeld festlegen weil variabel.

    Also ich bräuchte:

    $x = 'abcdefgh';
    $func = 'strtoupper($x)';
    $y = $func;
    echo $y;

    Aber so gehts leider nicht, bleibt dann doch nur  eval() ?

    Meike

    1. Hello,

      Wichtig ist für mich die Parameterübergabe, die

      siehe http://selfhtml.bitworks.de --> Array von Funktionen anlegen
      und
      http://selfhtml.bitworks.de/artikel_datenstrukturen/function_reference.php.txt

      Harzliche Grüße vom Berg
      http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau

  3. Hi Meike,

    Hatt mich schon darauf eingestellt eval nutzen zu müssen,
    aber wenn so geht, perfekt. Aber ist das richtig?
    Und wenn Ja, wie kommt das, dass PHP das so begreift?

    ja, das Konzept nennt sich "Variable functions".

    oder gibt es eine bessere Lösung?

    ich persönlich bevorzuge die Benutzung von call_user_func() oder die ähnliche call_user_func_array(), da ich es für übersichtlicher halte.

    Gruß,
    Andreas.

  4. Danke an alle,
    für die ausführliche Antworten, meine Hauptfage war ja sofort
    erledigt, der weitere Hintergrund erwies sich als äusserst
    spannende Ergänzung und Anregung call_user_func_array mal
    ein wenig zu gebrauchen.

    vg.
    Meike