Matthias Jütte: Funktionsaufruf in Funktion

Hallo!

Es ist doch grundsätzlich möglich eine Funktion innerhlab einer Funktion aufzurufen, oder?

Ich brüte schon den halben Tag an diesem Problem, wo das eben nicht der Fall zu sein scheint.

Funktion x (Datenbankabfrage mit Parametern aus Funktionsaufruf) wird in index.php eingebunden.

Funktion y ist in index.php definiert (nach der Einbindung) und ruft Funktion x auf. Da geht nix.

Ziehe ich Funktion x aus Funktion y raus läuft alles wie gewollt.

Wer schützt meinen Kopf vor'm Explodieren?

Gruß

Matthias

--
ss:| zu:| ls:[ fo:| de:] va:) ch:? sh:) n4:( rl:( br:> js:| ie:% fl:) mo:}
http://www.makaio.de/quotations
  1. Hi Matthias,

    Es ist doch grundsätzlich möglich eine Funktion innerhlab einer Funktion aufzurufen, oder?

    ja:

    <?php    #test2.php

    function x ($str)
    {
        return $str;
    }

    ?>

    <?php    #test.php

    error_reporting(E_ALL);

    include('./test2.php');

    function y ()
    {
        return x('test');
    }

    echo y();

    ?>

    gibt bei mir richtigerweise den String "test" aus.

    Ich brüte schon den halben Tag an diesem Problem, wo das eben nicht der Fall zu sein scheint.

    bei mir schon ;-)

    [...]
    Ziehe ich Funktion x aus Funktion y raus läuft alles wie gewollt.

    Wer schützt meinen Kopf vor'm Explodieren?

    Bekommst du keine Fehlermeldung?

    Gruß,
    Andreas.

    1. Hallo Andreas!

      Ich habe jetzt gerade die Lösung gefunden. Nochmal kurz zur Situation:

      *** functions.php

      function getSessVars ($sid, $varname) {
        if ($varname != "" ) {
          $andvar = " and varname = '$varname'";
        } else {
          $andvar = "";
        }

      $sql = "select varname, varvalue from sessvars where sid = '$sid'" . $andvar;
        $ret = @mysql_query($sql);

      $num=@mysql_num_rows ($ret);
        if ($num >= 0) {
          //
          // vars present
          //
          while($rs = mysql_fetch_row($ret)) {
            global $$rs[0];
            $$rs[0] = $rs[1]; <--- Hier wird automatisch der Variablenname generiert
          }
          return $num;
        } else {
          return false;
        }
      }

      *** index.php

      function output() {
          getSessVars($sid, "variable");
      }

      Das klappt nicht.

      Füge ich nun aber output() noch global $variable hinzu, dann läuft's. Daraus schließe ich, daß die Funktion sozusagen außerhalb output() läuft, wobei ich eigentlich vom Gegenteil überzeugt war.

      Ist meine Beobachtung richtig? Wie kann man es evtl. eleganter lösen, so daß man direkt auf die Variable zugreifen kann, egal wie tief man sich in Subroutinen eingegraben hat?

      Gruß

      Matthias

      --
      ss:| zu:| ls:[ fo:| de:] va:) ch:? sh:) n4:( rl:( br:> js:| ie:% fl:) mo:}
      http://www.makaio.de/quotations
      1. Hi Matthias,

        Wie kann man es evtl. eleganter lösen, so daß man direkt auf die Variable zugreifen kann, egal wie tief man sich in Subroutinen eingegraben hat?

        Indem die Funktion einen Wert return't und du dann per $output = funktion($variablen) den $output erhältst.

        Der Yeti

        --
        Habe nun, ach! WInfo, BWL, und Mathe, Und leider auch Info!
        Durchaus studiert, mit heißem Bemühn. Da steh' ich nun, ich armer Thor!
        Und bin so klug als wie zuvor!
        sh:( fo:| ch:? rl:? br:  n4:& ie:( mo:| va:| de:[ zu:) fl:| ss:) ls:< js:|
        http://community.de.selfhtml.org/fanprojekte/selfcode.htm
        1. Hallo!

          Das hatte ich auch schon überlegt.

          Aber ist es denn nun echt so, daß Funktionen immer auf der Ebene laufen, wo sie definiert wurden? Ich dacht durch den Aufruf würde an der entprechenden Stelle so eine Art include gemacht und die Variablendefinition somit in die Funktion, die den Aufruf macht, geholt.

          Gruß

          Matthias

          --
          ss:| zu:| ls:[ fo:| de:] va:) ch:? sh:) n4:( rl:( br:> js:| ie:% fl:) mo:}
          http://www.makaio.de/quotations
      2. Hi Matthias,

        Füge ich nun aber output() noch global $variable hinzu, dann läuft's. Daraus schließe ich, daß die Funktion sozusagen außerhalb output() läuft, wobei ich eigentlich vom Gegenteil überzeugt war.

        nein - sie läuft schon innerhalb von output(). Es gibt allerdings nur genau einen globalen Geltungsbereich für Variablen und der befindet sich _nicht_ in der Funktion output(). Durch das Schlüsselwort "global" in der while-Schleife gibst du der Funktion getSessVars() allerdings die Anweisung, die Werte im globalen Bereich zu ändern. Daher scheint es auch so, als laufe dein Script wie gewünscht, wenn du durch

        global $variable;

        der Funktion output() ebenfalls die Möglichkeit schaffst, auf den globalen Wert von $variable zuzugreifen.

        ABER: Es scheint eben nur so. Denn deine Funktion getSessVars() kann ja noch mehr: Bei Aufruf von getSessVars($sid, "") holt sie dir ja alle Variablen, die der SID entsprechen, aus der Datenbank. Hier werden sie alle mit dem Schlüsselwort global versehen, verändern also die Werte der Variablen im globalen Geltungsbereich. output() kann jedoch immernoch lediglich auf die globale Variable $variable zugreifen. In diesem Fall tut dein Script also wieder nicht das, was du willst.

        Wie kann man es evtl. eleganter lösen, so daß man direkt auf die Variable zugreifen kann, egal wie tief man sich in Subroutinen eingegraben hat?

        Entweder du gibst, wie Yeti schon sagte, aus getSessVars() die Werte zurück, wofür sich ein Array als Rückgabe anbieten würde. Die Anzahl der zurückgegebenen Werte kriegst du dann via count(). Oder du arbeitest mit "echten" Referenzen - getSessVars() bekommt einen weiteren Parameter als Referenz, in dem sie die Ergebnisse speichern darf:

        <?php

        function getSessVars ($sid, $varname, &$vars)
        {
            // ...
            while($rs = mysql_fetch_row($ret)) {

        $vars[$rs[0]] = $rs[1];

        }
            // ...
        }

        function output()
        {
            $vars = array();

        getSessVars($sid, "variable", $vars);
        }

        Nun referenzierst du in getSessVars() nicht mehr auf den globalen Geltungsbereich, sondern auf den Geltungsbereich, in dem die Funktion aufgerufen wurde, in diesem Fall also auf den in output(). In jedem Fall bietet sich aber ein Array an, einfach, da du evtl. mehrere Werte zurückgeben musst.

        Gruß,
        Andreas.