2014-09-11 7 views
1

Я работаю с классом оболочки Thread, который может принимать функцию и вызывать эту функцию в новом потоке. Это мой класс до сих пор:Сохранение анонимной функции в переменной класса из __construct

public function __construct($cbCallback, $aParameters) { 

    $this->cbCallback = $cbCallback; 
    $this->aParameters = $aParameters; 
    $this->return = false; 
} 

public function run() { 

    if (is_array($this->cbCallback)) { 

     $this->return = call_user_func($this->cbCallback, ...($this->aParameters)); 
    } 
    else { 

     $this->return = $this->cbCallback(...($this->aParameters)); 
    } 
} 

И это работает, используя часть call_user_func при приеме в функции обратного вызова. Я хотел бы перегрузить класс, чтобы он мог также принимать замыкание вместо массива обратного вызова. У меня возникли проблемы с сохранением анонимной функции как переменной класса: она всегда хранится как null.

Я положил некоторые отладочные в конструкторе:

echo "Paramater test 1: " . json_encode($cbCallback); 
$this->cbCallback = $cbCallback; 
echo "Paramater test 2: " . json_encode($cbCallback); 
echo "Variable test: " . json_encode($this->cbCallback); 

Это дает выход:

Paramater test 1: {} 
Paramater test 2: {} 
Variable test: null 

Я также попытался сделать $cbCallback проход по ссылке с &$cbCallback, что только приводит к ошибке что объект не может быть передан по ссылке.

Я чувствую, что есть либо специальное правило с анонимными функциями, либо что-то неуловимое происходит. Почему я не могу сохранить анонимную функцию в $ this-> cbCallback? Есть ли способ сохранить анонимную функцию в (не статической) переменной класса или что-то подобное, что будет работать одинаково, когда мне нужно вызвать эту функцию?

P.S. Я на PHP v5.6

+0

Это прекрасно работает для меня. – jgivoni

+0

, в какую версию php вы? Может возникнуть проблема с новейшей версией php. – TheBat

+0

Не уверен, но если это проблема с 5.6, я не могу попробовать. – jgivoni

ответ

1

Я, наконец, выследили вопрос у меня был. Оказывается, это проблема с библиотекой pthreads.

Указанный код работает отлично, если вы не расширяете класс Thread.

Я нашел сообщение об ошибке на сайте РНР: https://bugs.php.net/bug.php?id=67506

Затем отправил его в krakjoe-х GitHub: https://github.com/krakjoe/pthreads/issues/355

Оказывается, он исправил проблему пару часов до меня размещения, так это исправить issue, убедитесь, что вы используете pthreads v2.0.9 +.

0

В переменной класса можно сохранить замыкание или функцию лямбда-функции/анонимную функцию. Однако вы не можете сериализовать его, потому что это не просто значение, его функция.

+0

Мне не нужно сериализовать его. Мне просто нужно его хранить. Я не могу его хранить, иначе я бы не опубликовал вопрос. У меня нет проблем, что выходы просто {}. Проблема заключается в том, что третий выход равен нулю. – TheBat

+0

«Хранение» означает, что вы каким-то образом его сериализуете, а затем несериализуете, чтобы загрузить его в память. В противном случае вы не сможете использовать «сохраненные» данные позже. –

+0

Если функция может быть сохранена как $ func = function() {}; согласно http://php.net/manual/en/functions.anonymous.php, тогда его не нужно сериализовать, чтобы быть сохраненным в переменной, предполагая, что они действительно не подлежат анализу. – TheBat

1

Если вы хотите выполнить закрытие, которое вы сохранили в объекте, попробуйте сначала назначить его переменной, иначе вы можете получить «Вызов неопределенного метода».

Вместо

$this->return = $this->cbCallback(...($this->aParameters)); 

Попробуйте

$cb = $this->cbCallback; 
$this->return = $cb(...($this->aParameters)); 
+0

Благодарим вас за предложение. Возможно, это понадобится позже, но $ this-> cbCallback является нулевым в этой точке, поэтому даже сохранение в $ cb просто приведет к ссылке на нуль в новую переменную. – TheBat