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

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

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

  

 public function addRule(RuleInterface $routeRule, \Closure $callback)
{ if (false !== $callbackClosure = $callback->bindTo($routeRule, $routeRule)) {
$routeRule->setCallback($callbackClosure);
} else {
throw new InvalidRuleCallbackException('invalid callback closure specified!');
} if (!$routeRule->isTerminable()) {
array_unshift($this->_rules, $routeRule);
} else {
$this->_rules[] = $routeRule;
} return self::$_instance;
}

  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下就不报错了:

 

 public function addRule(RuleInterface $routeRule, \Closure $callback)
{
// must bind as a static Closure, otherwise will raise: Warning: Cannot bind an instance to a static closure(v5.x)
if (false !== $callbackClosure = \Closure::bind($callback, null, $routeRule)) {
$routeRule->setCallback($callbackClosure);
}
/*if (false !== $callbackClosure = $callback->bindTo($routeRule, $routeRule)) {
$routeRule->setCallback($callbackClosure);
}*/ else {
throw new InvalidRuleCallbackException('invalid callback closure specified!');
} if (!$routeRule->isTerminable()) {
array_unshift($this->_rules, $routeRule);
} else {
$this->_rules[] = $routeRule;
} return self::$_instance;
}

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

PHP 5.x和PHP 7 Closure不同行为问题的更多相关文章

  1. 深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  2. closure

    什么是闭包?百度的答案: 闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)."闭包&quo ...

  3. 使用Google Closure Compiler高级压缩Javascript代码注意的几个地方

    介绍 GCC(Google Closure Compiler)是由谷歌发布的Js代码压缩编译工具.它可以做到分析Js的代码,移除不需要的代码(dead code),并且去重写它,最后再进行压缩. 三种 ...

  4. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  5. 浅析匿名函数、lambda表达式、闭包(closure)区别与作用

    浅析匿名函数.lambda表达式.闭包(closure)区别与作用 所有的主流编程语言都对函数式编程有支持,比如c++11.python和java中有lambda表达式.lua和JavaScript中 ...

  6. 【转】深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  7. 学习Javascript闭包(Closure)

    闭包作用 1.让变量驻留在内存中 2.函数外部可以读取函数内部的私有变量 <!DOCTYPE html> <html lang="en"> <head ...

  8. JavaScript闭包(Closure)学习笔记

    闭包(closure)是JavaScript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 下面就是我的学习笔记,对于JavaScript初学者应该是很有用的. 一.变量的作用域 要理解 ...

  9. PHP 中的Closure

    PHP 中的Closure Closure,匿名函数,又称为Anonymous functions,是php5.3的时候引入的.匿名函数就是没有定义名字的函数.这点牢牢记住就能理解匿名函数的定义了. ...

  10. 如何创建C# Closure ?

    JavaScript中一个重要的概念就是闭包,闭包在JavaScript中有大量的应用,但是你知道么?C#也可以创建Closure.下面就介绍一下如何在C#中创建神奇的闭包. 在这之前,我们必须先知道 ...

随机推荐

  1. mac配置go使用gopm下载第三方包

    打开zshrc文件 vim ~/.zshrc 输入变量 export GOPATH="/Users/chennan/go" #这个自定义 export GOBIN=$GOPATH/ ...

  2. java学习笔记11-static关键字

    如果在类中使用static关键字创建方法,这种方法称为类方法,可以在这个类中直接引用.而不是用static创建的方法.这种方法称为对象方法(实例方法),需要创建对象后才能使用. package les ...

  3. Mysql 时间差(年、月、天、时、分、秒)

    SELECT TIME_TO_SEC(TIMEDIFF('2018-09-30 19:38:45', '2018-08-23 10:13:01')) AS DIFF_SECOND1, -- 秒 UNI ...

  4. vue 双向数据绑定的实现学习(一)

    前言:本系列学习笔记从以下几个点展开 什么是双向数据绑定 双向数据绑定的好处 怎么实现双向数据绑定 实现双向数据数据绑定需要哪些知识点 数据劫持 发布订阅模式 先看看我们要实现的目标是什么,如下动图: ...

  5. PHP 两数组循环组合

  6. SVG初尝试之path

    命令汇总 命令基本规律 移动和直线命令 弧线命令

  7. JS监听浏览器的返回、后退、上一页按钮的事件方法

    在实际的应用中,我们常常需要实现在移动app和浏览器中点击返回.后退.上一页等按钮实现自己的关闭页面.调整到指定页面或执行一些其它操作的需求,那在代码中怎样监听当点击微信.支付宝.百度糯米.百度钱包等 ...

  8. 论文阅读笔记五十:CornerNet: Detecting Objects as Paired Keypoints(ECCV2018)

    论文原址:https://arxiv.org/pdf/1808.01244.pdf github:https://github.com/princeton-vl/CornerNet 摘要 本文提出了目 ...

  9. Scrapy 隐含 bug: 强制关闭爬虫后从 requests.queue 读取的已保存 request 数量可能有误

    问题描述和解决方案已提交至 Scrapy issues: The size of requests.queue may be wrong when resuming crawl from unclea ...

  10. JMeter通过beanShell脚本生成随机手机号

    package xnzx; /** * @author xn088587 * */ public class getTel{ public static int getNum(int start,in ...