1

I'm having trouble passing a reference around a closure:

class stdobject {
    public function __call($method, $arguments) {    
        if (isset($this->{$method}) && is_callable($this->{$method})) {
            return call_user_func_array($this->{$method}, $arguments);
        } else {
            throw new Exception("Fatal error: Call to undefined method: $method");
        }
    }
}

$mod=function(){
  $test=new stdobject();

  $mode;

  $test->init=function($params) use (&$mode) {
    $mode =& $params['opmode'];
  };

  $test->setup=function() use (&$mode) {
    $mode='test';
  };

  return $test;
};

$opmode='helloworld';

$test=$mod();
$test->init([ 'opmode' => &$opmode ]);

$test->setup();

echo $opmode;  //should display test

I would like the setup function to modify $opmode in the outside scope, which would possibly not be the global scope, can anyone point me in the right direction on how to achieve this?

0

1 Answer 1

1

I am not sure why you would want this, but I guess this is what you were trying to achieve:

class stdobject {
    public function __call($method, $arguments) {    
        if (isset($this->{$method}) && is_callable($this->{$method})) {
            return call_user_func_array($this->{$method}, $arguments);
        } else {
            throw new Exception("Fatal error: Call to undefined method: $method");
        }
    }
}

$mod = function() {
    $self = new stdobject();

    $self->init = function ($params) use ($self) {
        $self->_opmode = &$params['opmode'];
    };

    $self->setup = function () use ($self) {
       $self->_opmode = 'dog';
    };

    $self->print = function () use ($self) {
        echo $self->_opmode . "\n";
    };

    return $self;
};

$obj = $mod();

$reference = 'fish';

$obj->init(['opmode' => &$reference]);
$obj->print();  // fish

$obj->setup();
$obj->print();  // dog

$reference = 'cats';
$obj->print();  // cats

https://3v4l.org/SLAri

However I prefer this:

<?php
class Mod {
    private $opmode;

    public function init($params)
    {
        $this->opmode = &$params['opmode'];
    }

    public function setup()
    {
        $this->opmode = 'dog';
    }

    public function print()
    {
        echo $this->opmode . "\n";
    }

}

$obj = new Mod();

$reference = 'fish';
$obj->init(['opmode' => &$reference]);
$obj->print();  // fish

$obj->setup();
$obj->print();  // dog

$reference = 'cats';
$obj->print();  // cats

https://3v4l.org/T9qr2

Sign up to request clarification or add additional context in comments.

8 Comments

hi, opmode is not available when the function is defined and needs to be passed by reference through the init function
@mattrichards See my update. Is this what you meant?
i edited it a bit further and now seems to do as i want :) any idea why i have to attach it to the self object, 3v4l.org/DfMVA
@mattrichards Don't quote me on this, but if you define the $opmode variable inside of $mod, whenever the $mod function returns, the $opmode variable goes out of scope and is garbage collected.
ok i refactored and put back in context of original question for future searches, here is a working version, 3v4l.org/gjY0g
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.