PHP 中`Closure`和`Callable`的區別以及在 Redis 訂閱方法中的使用

xugege發表於2019-07-04

它們的不同之處:Closure 必須是匿名函式,  callable 同時還可以為常規函式。
以下的例子中第一個會出現錯誤:

function callFunc1(Closure $closure) {
    $closure();
}

function callFunc2(Callable $callback) {
    $callback();
}

function xy() {
    echo 'Hello, World!';
}
$function = function() {
    echo 'Hello, World!';
};

callFunc1("xy"); // Catchable fatal error: Argument 1 passed to callFunc1() must be an instance of Closure, string given
callFunc2("xy"); // Hello, World!

callFunc1($function); // Hello, World!
callFunc2($function); // Hello, World!

//從php7.1開始可以使用以下程式碼轉換
callFunc1(Closure::fromCallable("xy"))

其中callable引數可以為

is_callable('functionName'); 
is_callable([$foo, 'bar']);//$foo->bar() 
is_callable(['foo','bar']);//foo::bar() 
is_callable(function(){});//closure

php中 redis的subscribe訂閱函式定義為

/**
 * Subscribe to a set of given channels for messages.
 * @param array|string  $channels
 * @param Closure  $callback
 * @return void
 */
public function subscribe($channels, Closure $callback)
{
  return $this->createSubscription($channels, $callback, __FUNCTION__);
}

專案中的應用

public function subscribeSellOrder(SellOrderProcess $sellOrderProcess)
{
  $closure = self::makeClosure($sellOrderProcess, 'sellOrdersProcess');
  $this->redis->subscribe(RtdataConst::SELL_CHANNEL_NAME, $closure);
}

protected static function makeClosure($obj, $method)
{
  return Closure::fromCallable([$obj, $method]);
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章