惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

腾讯CDC
aimingoo的专栏
aimingoo的专栏
S
SegmentFault 最新的问题
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 叶小钗
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
MyScale Blog
MyScale Blog
Stack Overflow Blog
Stack Overflow Blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 聂微东
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
Jina AI
Jina AI
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks

博客园 - yiyide266

[Express.js]next()函数的作用 [css]浏览器默认样式 have的实质 This comes after Chinese authorities announced an investigation against Mayday, in response to a viral video. [Linux]终端ssh远程连接如何保持 [PHP]PDO的dsn对mysql的连接影响 [javascript]端序(endian)和Buffer对象的read|write系列函数 vscode处理HTML标签两个光标的问题 intend,intent和indent [css]一个块格式化上下文(BFC)阻止外边距重叠的示例 [PHP_yaf]内部注册到spl_autoload的方法 [PHP_yaf]Yaf_Application [PHP_yaf]写在用户代码的配置项 [PHP_yaf]保存在php.ini中的配置项 [PHP]spl_autoload函数栈的向下遍历机制 [英语单词]关于战争 [MySql]1820错误码重置密码方法 [Linux]信号捕捉函数总是第一时间执行 [Linux]信号捕捉函数与exec
[PHP]回调函数参数(callable类型)的一些细节
yiyide266 · 2023-04-18 · via 博客园 - yiyide266
$foo = function(){
    echo "foo()\n";
};
$foo();
call_user_func($foo);

以上两种调用callable类型的语法是无问题的,函数可以正常运行

下面来说一下习惯上认为可行,但事实上不可行的两个调用方法
假设有以下代码,A实例的foo属性为一个callable:

class A{
    public $foo;
    public function bar(){
        echo "bar()\n";
    }
}
$t = new A();
$t->foo = function(){
    echo "foo()\n";
};

对对象调用方法的语法对callable类型无效,因为这个语法已经被php仅用于调用方法来解析,如果执行,php会提示:"Call to undefined method":

$t->foo(); //提示:"Call to undefined method"

调用call_user_func函数,第一个参数是callable有效:

call_user_func($t->foo); //正常调用

调用call_user_func函数,但使用重新指定上下文的形式无效,因为这种语法规定参数array的第二项是一个方法(或函数)名,而不是一个callable:

call_user_func(array($t, $t->foo)); //提示:"second array member is not a valid method"

想要实现重新定位上下文,只需要借助一下Closure :: bind()方法,它接受一个callable,重新返回一个指定了新的上下文的callable,然后再次用call_user_func函数普通的调用方式,就没问题:

call_user_func(Closure :: bind($t->foo, $t)); //Okay!