如何在PHP中定义不带参数的回调函数并在PHP中使用?
How to define a callback with parameters without closure and use in PHP?
在 PHP 中,为了定义回调,可以使用闭包,传递静态参数的工具是 use
指令。
class MyClass {
public function foo($x) {
echo $x;
}
public function bar() {
$x = '123';
$callback = function () use ($x) {
$this->foo($x);
};
$callback();
}
}
$myClass = new MyClass();
$myClass->bar();
是否可以/如何避免匿名函数,用方法代替?
class MyClass {
public function foo($x) {
echo $x;
}
public function baz() {
$x = '567';
// There is no function with the name create_user_func.
// Just to show, what I'm looking for.
$callback = create_callback([$this, 'foo'], $params = [$x]);
$callback();
}
}
$myClass = new MyClass();
$myClass->baz();
编辑:
一些额外的/背景信息(明确我想要实现的目标和原因 - 并避免误解):
在我的具体案例中,我需要将回调传递给框架的方法。这意味着:我不能/可能不会影响它被调用的方式。
该方法只接受回调本身,不接受回调参数。这意味着,回调必须 "know"/提供它需要的静态参数(及其值)。
正是 use
指令解决的问题。但是我的方法中有多个回调定义,而且方法越来越长。所以我想将回调的逻辑移动到单独的方法中。
有很多方法可以实现这一点。
- 使用辅助函数。
代码:
class MyClass {
private $x;
public function foo() {
echo $this->x;
}
public function bar() {
$this->x = '123';
anon($this);
}
}
$myClass = new MyClass();
$myClass->bar();
function anon($obj) {
$obj->foo();
}
- 使用
call_user_func
.
代码:
class MyClass {
private $x;
public function foo() {
echo $this->x;
}
public function bar() {
$this->x = '123';
call_user_func([$this, 'foo']);
}
}
$myClass = new MyClass();
$myClass->bar();
- 如果出于某种原因你不想使用成员变量,你可以通过
call_user_func_array
. 传递参数
代码:
class MyClass {
private $x;
public function foo($x) {
echo $x;
}
public function bar() {
$x = '123';
call_user_func_array([$this, 'foo'], [$x]);
}
}
$myClass = new MyClass();
$myClass->bar();
But I have multiple callback definitions in my method, and the method is getting long. So I want to move the logic of the callbacks to separate methods.
这是魔术方法的完美示例__invoke()
对于您需要的每个回调,将其使用的功能和属性提取到一个新的 class 中。将代码放入新的class的__invoke()
方法中,将它需要的所有属性初始化到它的__construct()
中,你就可以开始了。
代码:
class MyClass {
public function bar() {
$x = '123';
// Create the callback, pass the values it needs to initialize
$callback = new ActionFoo($x);
// Call the callback without arguments
$callback();
}
}
class ActionFoo {
private $x;
public function __construct($x) {
$this->x = $x;
}
public function __invoke() {
echo($this->x);
}
}
$myClass = new MyClass();
$myClass->bar();
我想可以公平地说,您正在尝试模仿 Javascript 的 bind
方法。 PHP 中的问题是函数不是第一个 class 公民或对象,所以像 ->bind($x)
这样的东西是不可能的。也没有办法为 callable
传递额外的参数。所以你要有把它包装在东西.
一个更可重用的方法是写一个合适的 class:
class CallbackWrapper {
protected $callable,
$args;
public function __construct(callable $callable, array $args) {
$this->callable = $callable;
$this->args = $args;
}
public function __invoke() {
call_user_func_array($this->callable, $this->args);
}
}
giveMeACallback(new CallbackWrapper([$this, 'foo'], [$x]));
或者你只是简化匿名函数的构造:
function make_callback(callable $callable, array $args) {
return function () use ($callable, $args) {
return call_user_func_array($callable, $args);
};
}
giveMeACallback(make_callback([$this, 'foo'], [$x]));
在 PHP 中,为了定义回调,可以使用闭包,传递静态参数的工具是 use
指令。
class MyClass {
public function foo($x) {
echo $x;
}
public function bar() {
$x = '123';
$callback = function () use ($x) {
$this->foo($x);
};
$callback();
}
}
$myClass = new MyClass();
$myClass->bar();
是否可以/如何避免匿名函数,用方法代替?
class MyClass {
public function foo($x) {
echo $x;
}
public function baz() {
$x = '567';
// There is no function with the name create_user_func.
// Just to show, what I'm looking for.
$callback = create_callback([$this, 'foo'], $params = [$x]);
$callback();
}
}
$myClass = new MyClass();
$myClass->baz();
编辑:
一些额外的/背景信息(明确我想要实现的目标和原因 - 并避免误解):
在我的具体案例中,我需要将回调传递给框架的方法。这意味着:我不能/可能不会影响它被调用的方式。
该方法只接受回调本身,不接受回调参数。这意味着,回调必须 "know"/提供它需要的静态参数(及其值)。
正是 use
指令解决的问题。但是我的方法中有多个回调定义,而且方法越来越长。所以我想将回调的逻辑移动到单独的方法中。
有很多方法可以实现这一点。
- 使用辅助函数。
代码:
class MyClass {
private $x;
public function foo() {
echo $this->x;
}
public function bar() {
$this->x = '123';
anon($this);
}
}
$myClass = new MyClass();
$myClass->bar();
function anon($obj) {
$obj->foo();
}
- 使用
call_user_func
.
代码:
class MyClass {
private $x;
public function foo() {
echo $this->x;
}
public function bar() {
$this->x = '123';
call_user_func([$this, 'foo']);
}
}
$myClass = new MyClass();
$myClass->bar();
- 如果出于某种原因你不想使用成员变量,你可以通过
call_user_func_array
. 传递参数
代码:
class MyClass {
private $x;
public function foo($x) {
echo $x;
}
public function bar() {
$x = '123';
call_user_func_array([$this, 'foo'], [$x]);
}
}
$myClass = new MyClass();
$myClass->bar();
But I have multiple callback definitions in my method, and the method is getting long. So I want to move the logic of the callbacks to separate methods.
这是魔术方法的完美示例__invoke()
对于您需要的每个回调,将其使用的功能和属性提取到一个新的 class 中。将代码放入新的class的__invoke()
方法中,将它需要的所有属性初始化到它的__construct()
中,你就可以开始了。
代码:
class MyClass {
public function bar() {
$x = '123';
// Create the callback, pass the values it needs to initialize
$callback = new ActionFoo($x);
// Call the callback without arguments
$callback();
}
}
class ActionFoo {
private $x;
public function __construct($x) {
$this->x = $x;
}
public function __invoke() {
echo($this->x);
}
}
$myClass = new MyClass();
$myClass->bar();
我想可以公平地说,您正在尝试模仿 Javascript 的 bind
方法。 PHP 中的问题是函数不是第一个 class 公民或对象,所以像 ->bind($x)
这样的东西是不可能的。也没有办法为 callable
传递额外的参数。所以你要有把它包装在东西.
一个更可重用的方法是写一个合适的 class:
class CallbackWrapper {
protected $callable,
$args;
public function __construct(callable $callable, array $args) {
$this->callable = $callable;
$this->args = $args;
}
public function __invoke() {
call_user_func_array($this->callable, $this->args);
}
}
giveMeACallback(new CallbackWrapper([$this, 'foo'], [$x]));
或者你只是简化匿名函数的构造:
function make_callback(callable $callable, array $args) {
return function () use ($callable, $args) {
return call_user_func_array($callable, $args);
};
}
giveMeACallback(make_callback([$this, 'foo'], [$x]));