php - 带有闭包的意外命名空间行为
问题描述
使用 PHP 7.0,考虑下面的代码:
<?php
namespace A {
$closure = function() {
echo __NAMESPACE__;
};
}
namespace B {
$closure = function () {
echo __NAMESPACE__;
};
}
namespace C {
$closure();
}
对我来说,预期的输出是:
PHP Notice: Undefined variable: closure
但不知何故,结果是
B
然后考虑下面的代码:
<?php
namespace A {
$closure = function() {
echo __NAMESPACE__;
};
}
namespace B {
$closure = function () {
echo __NAMESPACE__;
};
}
namespace C {
\A\$closure();
}
现在知道(但尚未理解)第一个示例的行为,我的预期输出将是:
A
但相反我得到
PHP Parse error: syntax error, unexpected '$closure' (T_VARIABLE), expecting identifier (T_STRING)
这种行为完全让我感到困惑。
问题第 1 部分:有人可以解释我在第一个示例中的期望有什么问题吗?问题第 2 部分:行为如何与第一个示例一致?
解决方案
您观察到的行为不应使您感到困惑。这是应该发生的事情。这正是 PHP 命名空间的工作方式。
PHP手册解释:
PHP 命名空间提供了一种对相关类、接口、函数和常量进行分组的方法。
不是变量。
这意味着$closure
在您的代码中,您定义的所有命名空间(A、B 和 C)中的变量完全相同。它首先在命名空间 A 中定义。然后在命名空间 B 中替换值。然后在命名空间 C 中调用它包含的闭包。
第二个例子也是一样的。因为命名空间不用于对变量进行分组,所以很明显这\A\$closure()
是一种无效的语法。
推荐阅读
- python - 在哪里运行在线 Python 3.8 脚本
- hibernate - 如何在 kotlin-script 中设置 Hibernate Gradle 插件?
- mysql - MYSQL数据库重启后拒绝访问
- mysql - 多个子查询,计算更多儿子但有条件
- python - 如何在列表中加入某个字符串值
- xaml - 如何在小屏幕上实现 Xamarin Forms SwipeGesture
- spring-boot - java.lang.AssertionError: Status expected:<200 OK> but was:<404 NOT_FOUND> for WebFluxTest
- java - 使用 JFormattedTextField(NumberFormat.getIntegerInstance()) 时出错;
- laravel - 如何限制/限制可以访问存储文件夹中文件的用户?(拉拉维尔)
- powerbi - 如何使用 PowerBI 上的 DAX 查询从现有表创建新表?