首页 > 代码库 > PHP 5.x和PHP 7 Closure不同行为问题

PHP 5.x和PHP 7 Closure不同行为问题

  同样一段闭包代码,PHP 7 ok的,PHP 5.5.11(Windows 开发机器)上却报错,以为是PHP 5 bug,原来是用法不对,记录一下~

 

  原代码(自己写的框架的路由部分)最初是这样写的:

  完整代码地址: https://github.com/TF-Joynic/Hydrogen/blob/master/lib/Hydrogen/Route/Router.php

  

 1 public function addRule(RuleInterface $routeRule, \Closure $callback)
 2     {
 3         
 4         if (false !== $callbackClosure = $callback->bindTo($routeRule, $routeRule)) {
 5             $routeRule->setCallback($callbackClosure);
 6         } else {
 7             throw new InvalidRuleCallbackException(‘invalid callback closure specified!‘);
 8         }
 9 
10         if (!$routeRule->isTerminable()) {
11             array_unshift($this->_rules, $routeRule);
12         } else {
13             $this->_rules[] = $routeRule;
14         }
15 
16         return self::$_instance;
17     }

  PHP 7下面跑却是没有问题

  但是5.5.11下运行的时候,第4行直接抛 Warning: Cannot bind an instance to a static closure

    传进来的 $callback Closure 实际是:

  

function (Request $request, Response $response) {}

  

  初步判断在5.5环境下PHP认为它是一个static function,而PHP 7下跑的时候可能就认为是普通function

  修改代码,以static 的方式bind闭包,php 5下就不报错了:

 

 1 public function addRule(RuleInterface $routeRule, \Closure $callback)
 2     {
 3         // must bind as a static Closure, otherwise will raise: Warning: Cannot bind an instance to a static closure(v5.x)
 4         if (false !== $callbackClosure = \Closure::bind($callback, null, $routeRule)) {
 5             $routeRule->setCallback($callbackClosure);
 6         }
 7         /*if (false !== $callbackClosure = $callback->bindTo($routeRule, $routeRule)) {
 8             $routeRule->setCallback($callbackClosure);
 9         }*/ else {
10             throw new InvalidRuleCallbackException(‘invalid callback closure specified!‘);
11         }
12 
13         if (!$routeRule->isTerminable()) {
14             array_unshift($this->_rules, $routeRule);
15         } else {
16             $this->_rules[] = $routeRule;
17         }
18 
19         return self::$_instance;
20     }

 

  具体是不是上述原因有待细究……

 

PHP 5.x和PHP 7 Closure不同行为问题