__invoke () для вызываемого массива или строки

Как написать PHP-код для вызова всех «Callables» с __invoke()?

Желание здесь передать по ссылке, которая устарела с call_user_func[_array](), Я видел, что там есть пакет, TRex\Reflection\CallableReflection, но это, кажется, использовать call_user_func() на заднем плане, и пострадает та же проблема.

<?php

function passthrough_invoke(callable $callback) {
return $callback->__invoke();
}

function passthrough_user(callable $callback) {
return call_user_func($callback);
}

function test_func() { return "func_string\n"; };

class test_obj {

function test_method() {
return "obj_method\n";
}
}
print_r("Call User Func Works:\n");
echo passthrough_user(function() { return "func_closure\n"; });
echo passthrough_user(array(new test_obj, 'test_method'));
echo passthrough_user('test_func');

print_r("\n__invoke dies:\n");
echo passthrough_invoke(function() { return "func_closure\n"; });
echo passthrough_invoke(array(new test_obj, 'test_method'));
echo passthrough_invoke('test_func');

Этот вопрос может также прозвучать так: «Есть ли способ, который не следует считать устаревшим, когда вы можете вызвать обратный вызов с передачей по ссылке?», Но я нахожу текущий вопрос более интересным.

Заметки:

Основная цель — сделать функцию обратного вызова полноценной функцией и иметь все тонкости этого, в том числе Pass By Reference, которая __invoke($args, ...) позволяет.

с помощью func_get_args(), или же ...$args (переменная функция на обертке) не будет работать, так как вы все равно останетесь с помощью call_user_func_array($callback, $arg_array), который не будет поддерживать Pass By Reference.

Примечания 2:

Я только что узнал, что вы можете ВЫЗВАТЬ, используя переменные параметры, а также в следующем PHP: function_name(...$args), Эта поддержка передается по ссылке?

Далее мы все еще сталкиваемся с проблемой, которая $callback_array = array($object, 'method'); вызываемый, но не $callback_array();и, конечно, не $callback_array(...$args);, Кроме того, я должен уточнить, что вопрос на самом деле о написании кода, который не сломается в более поздних выпусках, которые могут это сделать.

IE: я могу написать это сейчас, запустить его завтра.

Который выглядит все тусклее и тусклее перспективы.

2

Решение

Это легко реализовать для вызова члена класса:

<?php

function passthrough_invoke(callable $callback) {
return $callback->__invoke();
}

function passthrough_user(callable $callback) {
return call_user_func($callback);
}

function test_func() { return "func_string\n"; };

class test_obj {
public function test_method() {
return "obj_method\n";
}
}

class CallableWrapper {
private $inst, $meth;
public function __construct( $inst, $meth ) {
$this->inst = $inst;
$this->meth = $meth;
}
public function __invoke() {
echo $this->inst->{$this->meth}();
}
}

print_r("Call User Func Works:\n");
echo passthrough_user(function() { return "func_closure\n"; });
echo passthrough_user(array(new test_obj, 'test_method'));
echo passthrough_user('test_func');

print_r("\n__invoke rocks:\n");
echo passthrough_invoke( function() { return "func_closure\n"; } );
echo passthrough_invoke(
new CallableWrapper( new test_obj, 'test_method' )
);

// ⇒
// __invoke rocks:
// func_closure
// obj_method

Для глобальной области видимости это также должно быть выполнимо, но я отказываюсь пытаться реализовать неправильные шаблоны 🙂

0

Другие решения

Других решений пока нет …