PHP 5.3 > 5.4 / Probleme mit (Parameter n to function() expected to be a reference, v

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • PHP 5.3 > 5.4 / Probleme mit (Parameter n to function() expected to be a reference, v

    Hi,

    ich hatte unter PHP 5.3 ein Script laufen, welches ohne Probleme lief. Nach Umstellung auf Debian 6 und damit auf PHP 5.4 erhalte ich eine Fehlermeldung. Kann mir bitte einer sagen, warum das nicht mehr geht, und/oder was ich besser machen kann?

    Das Script hier mal auf das Wesentliche reduziert:

    PHP Code:
    <?php

    class MyClass
    {
        public function 
    __construct()
        {
            
    $this->my_external_handler 'my_external_user_function';
            declare(
    ticks 1);
            
    pcntl_signal(SIGINT, array($this"signal_handler"));
        }
        
        public function 
    signal_handler($signal_number)
        {
            
    $this->info "signal $signal_number caught";
            
    call_user_func($this->my_external_handler$this);
        }
    }

    ini_set("display_errors"1); 
    ini_set("error_reporting"E_ALL);

    $TestClass = new MyClass;

    $i 10;
    while(
    $i--) {
        echo(
    "Waiting $i seconds for SIGINT (CONTROL+C) ...\n");
        
    sleep(1);
    }

    function 
    my_external_user_function(&$data)
    {
        echo(
    "info: '".$data->info."'\n");
        exit;
    }
      
    ?>
    Wenn ich es in der Shell wie folgt ausführe
    Code:
    php test.php
    dann erhalte ich die Meldung:
    Code:
    Parameter 1 to my_external_user_function() expected to be a reference, value given in /var/lib/asterisk/agi-bin/test.php on line 15
    Wenn ich Zeile 15 wie folgt ändere, dann klappt es:
    PHP Code:
    call_user_func($this->my_external_handler, &$this); 
    Aber: Ist das so richtig?

  • #2
    Warum verwendest du hier eine Referenz? Lass sie doch einfach weg.

    Comment


    • #3
      Ja hier in der reduzierten Form wäre das kein Problem. In meinem Script spielt das schon eine Rolle ... Unabhängig davon wüsste ich schon gerne, warum das nicht mehr geht.

      Comment


      • #4
        Originally posted by thotti View Post
        Ja hier in der reduzierten Form wäre das kein Problem. In meinem Script spielt das schon eine Rolle ... Unabhängig davon wüsste ich schon gerne, warum das nicht mehr geht.
        Dann zeig bitte ein Beispiel, wo das so notwendig ist. Ich seh keine Notwendigkeit für eine Referenz. Mit Fantasiecode, der nichts mit dem Problem zu tun hat, kann man schlecht arbeiten.

        Comment


        • #5
          PHP Code:
          call_user_func($this->my_external_handler, &$this); 
          Aber: Ist das so richtig?
          Nein!
          Das ist Unsinn!
          Denn $this ist IMMER eine Referenz.
          Wir werden alle sterben

          Comment


          • #6
            Originally posted by combie View Post
            Nein!
            Das ist Unsinn!
            Denn $this ist IMMER eine Referenz.
            $this ist immer ein Objekt, aber keine Referenz, jedenfalls nicht in PHP 5. Ich würde den Parameter $data einfach als MyClass typen und fertig. Es gibt keinen Grund, ihn als Referenz zu deklarieren.
            [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
            Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
            Super, danke!
            [/COLOR]

            Comment


            • #7
              Originally posted by AmicaNoctis View Post
              Ich würde den Parameter $data einfach als MyClass typen und fertig.
              Was heisst das bitte?

              Comment


              • #8
                Originally posted by thotti View Post
                Was heisst das bitte?
                PHP Code:
                function my_external_user_function (MyClass $data) {
                    
                // ...

                Alles was du in dieser Funktion mit $data anstellst, wird sich auf das übergebene Objekt auswirken. Es gibt also keinen Grund für eine Referenz. Du darfst $data nur keinen völlig neuen Wert zuweisen.
                [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                Super, danke!
                [/COLOR]

                Comment


                • #9
                  Originally posted by AmicaNoctis View Post
                  PHP Code:
                  function my_external_user_function (MyClass $data) {
                      
                  // ...

                  Danke - wo kann ich darüber bitte mehr lesen? Das habe ich noch nie gesehen. "Casten" ansich kenne ich - aber nicht so.

                  Und noch eine Frage bitte: Damit wäre es also eigentlich egal, ob ich eine Referenz übergebe und dies als Refernz in der Funktion deklariere ODER ob ich als value übergebe und dies ebenso in der Funktion als value angebe? Oder anders: die folgenden Varianten sind praktisch(!) identisch?

                  1)
                  call_user_func($this->my_external_handler, $this);
                  [...]
                  function my_external_user_function($data)

                  2)
                  call_user_func($this->my_external_handler, &$this);
                  [...]
                  function my_external_user_function(&$data)

                  Comment


                  • #10
                    Originally posted by thotti View Post
                    Danke - wo kann ich darüber bitte mehr lesen?
                    PHP: Type Hinting - Manual

                    Originally posted by thotti View Post
                    Und noch eine Frage bitte: Damit wäre es also eigentlich egal, ob ich eine Referenz übergebe und dies als Refernz in der Funktion deklariere ODER ob ich als value übergebe und dies ebenso in der Funktion als value angebe?
                    Wenn ein Parameter als Referenz deklariert ist, wird immer eine Referenz übergeben. Wenn du dann myfunc(&$var) aufrufst (statt myfunc($var)), kommt sogar eine Fehlermeldung (ab PHP 5.4 sogar als Fatal Error).

                    Egal ist es allerdings nicht ganz. Referenzen sollten nach Möglichkeit gar nicht benutzt werden und wenn doch, dann aus gutem Grund. Wenn man sauber objektorientiert arbeitet, braucht man sie in der Regel erst recht nicht.

                    Originally posted by thotti View Post
                    Oder anders: die folgenden Varianten sind praktisch(!) identisch?

                    1)
                    call_user_func($this->my_external_handler, $this);
                    [...]
                    function my_external_user_function($data)

                    2)
                    call_user_func($this->my_external_handler, &$this);
                    [...]
                    function my_external_user_function(&$data)
                    Das kommt darauf an, was du mit $data machst. Abgesehen davon, dass die zweite Variante wie gesagt ungültig ist, wirst du vermutlich dasselbe Resultat sehen, also ist es praktisch fast gleich, allerdings würde ich nicht behaupten „identisch“.
                    [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                    Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                    Super, danke!
                    [/COLOR]

                    Comment


                    • #11
                      Gelöst

                      Danke an alle!

                      Comment


                      • #12
                        Originally posted by thotti View Post
                        die folgenden Varianten sind praktisch(!) identisch?
                        Nein. Ein $this als Referenz zu übergeben, macht generell keinen Sinn, weil $this nicht überschrieben werden kann.

                        Bei anderen Objekten wirkt es sich so aus:

                        PHP Code:
                        function doSomething($object) {
                            
                        $object->bar 2;
                            
                        $object null;
                        }

                        $foo = new foo();
                        $foo->bar 1;
                        doSomething($foo);
                        var_dump($foo);

                        // object(foo)#1 (1) {
                        //   ["bar"]=>
                        //   int(2)
                        // } 
                        PHP Code:
                        function doSomething(&$object) {
                            
                        $object->bar 2;
                            
                        $object null;
                        }

                        $foo = new foo();
                        $foo->bar 1;
                        doSomething($foo);
                        var_dump($foo);

                        // NULL 
                        Wie du hier siehst, kann es ziemlich gefährlich werden, wenn du ein Objekt als Referenz übergibst, weil du so Objekte löschen/überschreiben kannst, die noch an anderer Stelle gebraucht werden. Deswegen ist ganz klar darauf zu verzichten.
                        Last edited by h3ll; 01-07-2011, 13:20.

                        Comment


                        • #13
                          @h3ll: Genau, schönes Beispiel!
                          [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                          Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                          Super, danke!
                          [/COLOR]

                          Comment

                          Working...
                          X