how to invoke ReflectionMethod and pass variable by reference asargument?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • rafal.m

    how to invoke ReflectionMethod and pass variable by reference asargument?

    Hi

    This code fails:

    class K2 {

    public function increment(&$obj ) {
    $obj += 1;
    }

    }

    $a = new K2();
    $c = 10;
    echo "before: $c <br/>\n";

    $rc = new ReflectionClass ('K2');
    $rm = $rc->getMethod('inc rement');
    $rm->invoke($a ,$c);

    echo "after: $c <br/>\n";


    and the outcome is:

    Fatal error: Uncaught exception 'ReflectionExce ption' with message
    'Invocation of method K2::increment() failed' in /temptest.php:17
    Stack trace: #0 /temptest.php(17 ): ReflectionMetho d-
    >invoke(Object( K2), 10) #1 {main} thrown in /temptest.php on line 17
    where line 17 is : $rm->invoke($a ,$c);

    but if i change line 5:
    from
    public function increment(&$obj )
    to

    public function increment($obj)

    it will work fine, but the echo before and after will the same :) (no
    $c increasing)

    of course if change line 17
    from
    $rm->invoke($a ,$c);
    to
    $rm->invoke($a ,&$c);

    i will have outcome
    before $c == 10
    after $c == 11

    but also php engine will throw new worrning:
    Warning: Call-time pass-by-reference has been deprecated; If you would
    like to pass it by reference, modify the declaration of [runtime
    function name](). If you would like to enable call-time pass-by-
    reference, you can set allow_call_time _pass_reference to true in your
    INI file. in /temptest.php on line 17

    I can write some wrapper to send variables by reference but it wont be
    clean solution.. do you have any other ideas?

    thanks for your time
    rafal

    ps. I also don't want to change allow_call_time _pass_reference = Off
    in php.ini file...



  • Egbert Teeselink

    #2
    Re: how to invoke ReflectionMetho d and pass variable by reference asargument?

    $rc = new ReflectionClass ('K2');
    $rm = $rc->getMethod('inc rement');
    $rm->invoke($a ,$c);
    Weird indeed.
    Does it work when using call_user_func, or call_user_func_ array maybe?
    like call_user_func( array($a, 'increment'), $c) or something. it may
    be the reflection lib. or i'm missing something.

    Comment

    • rafal.m

      #3
      Re: how to invoke ReflectionMetho d and pass variable by reference asargument?

      On 30 Maj, 23:48, Egbert Teeselink <skreb...@gmail .comwrote:
      $rc = new ReflectionClass ('K2');
      $rm = $rc->getMethod('inc rement');
      $rm->invoke($a ,$c);
      >
      Weird indeed.
      Does it work when using call_user_func, or call_user_func_ array maybe?
      like call_user_func( array($a, 'increment'), $c) or something. it may
      be the reflection lib. or i'm missing something.
      both:
      call_user_func( array($a, 'increment'), $c);
      and
      call_user_metho d('increment',$ a,$c);
      gave me the same outcome:

      before: 10
      after: 10

      r.

      Comment

      • Rik Wasmus

        #4
        Re: how to invoke ReflectionMetho d and pass variable by reference as argument?

        On Fri, 30 May 2008 23:01:39 +0200, rafal.m <rafal.m.malino wski@gmail.com
        wrote:
        Hi
        >
        This code fails:
        >
        class K2 {
        >
        public function increment(&$obj ) {
        $obj += 1;
        }
        >
        }
        >
        $a = new K2();
        $c = 10;
        echo "before: $c <br/>\n";
        >
        $rc = new ReflectionClass ('K2');
        $rm = $rc->getMethod('inc rement');
        $rm->invoke($a ,$c);
        >
        echo "after: $c <br/>\n";
        >
        >
        and the outcome is:
        >
        Fatal error: Uncaught exception 'ReflectionExce ption' with message
        'Invocation of method K2::increment() failed' in /temptest.php:17
        Stack trace: #0 /temptest.php(17 ): ReflectionMetho d-
        >invoke(Object( K2), 10) #1 {main} thrown in /temptest.php on line 17
        >
        where line 17 is : $rm->invoke($a ,$c);
        >
        but if i change line 5:
        from
        public function increment(&$obj )
        to
        >
        public function increment($obj)
        >
        it will work fine, but the echo before and after will the same :) (no
        $c increasing)
        >
        of course if change line 17
        from
        $rm->invoke($a ,$c);
        to
        $rm->invoke($a ,&$c);
        >
        i will have outcome
        before $c == 10
        after $c == 11
        >
        but also php engine will throw new worrning:
        Warning: Call-time pass-by-reference has been deprecated; If you would
        like to pass it by reference, modify the declaration of [runtime
        function name](). If you would like to enable call-time pass-by-
        reference, you can set allow_call_time _pass_reference to true in your
        INI file. in /temptest.php on line 17
        >
        I can write some wrapper to send variables by reference but it wont be
        clean solution.. do you have any other ideas?
        It's sad we have to resort to trickery, but here it is:
        <?php
        class K2 {
        public function increment(&$obj ) {
        $obj += 1;
        }
        }

        $a = new K2();
        $c = 10;
        echo "before: $c <br/>\n";
        $rc = new ReflectionClass ('K2');
        $rm = $rc->getMethod('inc rement');
        $rm->invokeArgs($ a ,array(&$c));
        echo "after: $c <br/>\n";
        ?>
        --
        Rik Wasmus
        ....spamrun finished

        Comment

        • Rik Wasmus

          #5
          Re: how to invoke ReflectionMetho d and pass variable by reference as argument?

          On Fri, 30 May 2008 23:57:20 +0200, rafal.m <rafal.m.malino wski@gmail.com
          wrote:
          On 30 Maj, 23:48, Egbert Teeselink <skreb...@gmail .comwrote:
          $rc = new ReflectionClass ('K2');
          $rm = $rc->getMethod('inc rement');
          $rm->invoke($a ,$c);
          >>
          >Weird indeed.
          >Does it work when using call_user_func, or call_user_func_ array maybe?
          >like call_user_func( array($a, 'increment'), $c) or something. it may
          >be the reflection lib. or i'm missing something.
          >
          both:
          call_user_func( array($a, 'increment'), $c);
          and
          call_user_metho d('increment',$ a,$c);
          gave me the same outcome:
          >
          before: 10
          after: 10
          As the manual states:
          call_user_func( ):
          Note: Note that the parameters for call_user_func( ) are not passed by
          reference.
          call_user_func_ array():
          Note: Referenced variables in param_arr are passed to the function by a
          reference, others are passed by a value. In other words, it does not
          depend on the function signature whether the parameter is passed by a
          value or by a reference.

          call_user_func_ array(array($a, 'increment'),ar ray(&$c));

          I suspect they have deployed similar code under the hood as
          call_user_func( _array) in the implementation of the ReflectionMetho d
          invoke()/invokeArgs(). Certainly annoying when the function signature
          should just be followed IMHO.
          --
          Rik Wasmus
          ....spamrun finished

          Comment

          • rafal.m

            #6
            Re: how to invoke ReflectionMetho d and pass variable by reference asargument?

            On 31 Maj, 00:38, "Rik Wasmus" <luiheidsgoe... @hotmail.comwro te:
            On Fri, 30 May 2008 23:01:39 +0200, rafal.m <rafal.m.malino w...@gmail.com> 
            wrote:
            >
            >
            >
            Hi
            >
            This code fails:
            >
            class K2 {
            >
               public function increment(&$obj ) {
                       $obj += 1;
               }
            >
            }
            >
            $a = new K2();
            $c = 10;
            echo "before: $c <br/>\n";
            >
            $rc = new ReflectionClass ('K2');
            $rm = $rc->getMethod('inc rement');
            $rm->invoke($a ,$c);
            >
            echo "after: $c <br/>\n";
            >
            and the outcome is:
            >
            Fatal error: Uncaught exception 'ReflectionExce ption' with message
            'Invocation of method K2::increment() failed' in /temptest.php:17
            Stack trace: #0 /temptest.php(17 ): ReflectionMetho d-
            invoke(Object(K 2), 10) #1 {main} thrown in /temptest.php on line 17
            >
            where line 17 is : $rm->invoke($a ,$c);
            >
            but if i change line 5:
            from
               public function increment(&$obj )
            to
            >
               public function increment($obj)
            >
            it will work fine, but the echo before and after will the same :) (no
            $c increasing)
            >
            of course if change line 17
            from
               $rm->invoke($a ,$c);
            to
               $rm->invoke($a ,&$c);
            >
            i will have outcome
            before $c == 10
            after $c == 11
            >
            but also php engine will throw new worrning:
            Warning: Call-time pass-by-reference has been deprecated; If you would
            like to pass it by reference, modify the declaration of [runtime
            function name](). If you would like to enable call-time pass-by-
            reference, you can set allow_call_time _pass_reference to true in your
            INI file. in /temptest.php on line 17
            >
            I can write some wrapper to send variables by reference but it wont be
            clean solution.. do you have any other ideas?
            >
            It's sad we have to resort to trickery, but here it is:
            <?php
            class K2 {
                    public function increment(&$obj ) {
                            $obj += 1;
                    }
            >
            }
            >
            $a = new K2();
            $c = 10;
            echo "before: $c <br/>\n";
            $rc = new ReflectionClass ('K2');
            $rm = $rc->getMethod('inc rement');
            $rm->invokeArgs($ a ,array(&$c));
            echo "after: $c <br/>\n";
            ?>
            --
            Rik Wasmus
            ...spamrun finished
            so it is not a bug :) it is the feature of php ;)

            thanks :) nice and easy :)
            I don't know why I didn't think about it ;D


            regards
            rafal

            Comment

            Working...