matt richards
matt richards

Reputation: 13

php variable reference within closure

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?

Upvotes: 1

Views: 65

Answers (1)

Pieter van den Ham
Pieter van den Ham

Reputation: 4484

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

Upvotes: 1

Related Questions