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

Posted Joynic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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不同行为问题的主要内容,如果未能解决你的问题,请参考以下文章

PHP-FPM docker 容器根据引擎(docker-compose 和 swarm)有不同的行为

PHP 版本从 5.x 升级到 7.x

php Closure类 闭包 匿名函数

转:php中的匿名函数和闭包(closure)

PHP Closure 类的bind简介和使用

php匿名函数和闭包函数及use关键字传参及Closure匿名函数类