ссылка на переменную php внутри замыкания

#php

#php

Вопрос:

У меня возникли проблемы с передачей ссылки вокруг замыкания:

 class stdobject {
    public function __call($method, $arguments) {    
        if (isset($this->{$method}) amp;amp; 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 (amp;$mode) {
    $mode =amp; $params['opmode'];
  };

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

  return $test;
};

$opmode='helloworld';

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

$test->setup();

echo $opmode;  //should display test
  

Я хотел бы, чтобы функция настройки изменялась $opmode во внешней области, которая, возможно, не была бы глобальной областью, кто-нибудь может указать мне правильное направление относительно того, как этого добиться?

Ответ №1:

Я не уверен, зачем вам это нужно, но я предполагаю, что это то, чего вы пытались достичь:

 class stdobject {
    public function __call($method, $arguments) {    
        if (isset($this->{$method}) amp;amp; 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 = amp;$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' => amp;$reference]);
$obj->print();  // fish

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

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

https://3v4l.org/SLAri

Однако я предпочитаю это:

 <?php
class Mod {
    private $opmode;

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

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

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

}

$obj = new Mod();

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

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

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

https://3v4l.org/T9qr2

Комментарии:

1. привет, режим работы недоступен, когда функция определена, и его необходимо передать по ссылке через функцию init

2. @mattrichards Смотрите мое обновление. Это то, что вы имели в виду?

3. я отредактировал ее немного дальше и теперь, похоже, делаю так, как хочу 🙂 есть идеи, почему я должен прикрепить ее к объекту self, 3v4l.org/DfMVA

4. @mattrichards Не цитируйте меня по этому поводу, но если вы определяете $opmode переменную внутри $mod , всякий раз, когда $mod функция возвращает, $opmode переменная выходит за пределы области видимости и собирается мусор.

5. хорошо, я переработал и вернул в контекст исходного вопроса для будущих поисков, вот рабочая версия, 3v4l.org/gjY0g