根据大多数编程语言的作用域规则,我可以访问在函数内部定义的变量,但是为什么此代码不起作用?
<?php
$data = 'My data';
function menugen() {
echo "[" . $data . "]";
}
menugen();
?>
输出为[]
。
根据大多数编程语言的作用域规则,我可以访问在函数内部定义的变量,但是为什么此代码不起作用?
<?php
$data = 'My data';
function menugen() {
echo "[" . $data . "]";
}
menugen();
?>
输出为[]
。
Answers:
它不起作用,因为您必须声明要访问的全局变量:
$data = 'My data';
function menugen() {
global $data; // <-- Add this line
echo "[" . $data . "]";
}
menugen();
否则,您可以通过访问它$GLOBALS['data']
。请参阅可变范围。
即使有些偏离主题,我还是建议您完全避免使用全局变量,而更希望将其作为参数传递。
This script will not produce any output because the echo statement refers to a local version of the $a variable, and it has not been assigned a value within this scope.
您可以执行以下操作之一:
<?php
$data = 'My data';
function menugen() {
global $data;
echo "[" . $data . "]";
}
menugen();
要么
<?php
$data = 'My data';
function menugen() {
echo "[" . $GLOBALS['data'] . "]";
}
menugen();
话虽这么说,过度使用全局变量可能会导致某些不良代码。通常最好传递您的需求。例如,应该引用数据库的句柄并对其执行操作,而不是引用全局数据库对象。这称为依赖注入。实施自动化测试(应该这样做)会使您的生活变得更加轻松。
这是范围的问题。简而言之,应避免使用全局变量,因此:
您要么需要将其作为参数传递:
$data = 'My data';
function menugen($data)
{
echo $data;
}
或者将其放在班级中并访问
class MyClass
{
private $data = "";
function menugen()
{
echo this->data;
}
}
也可以参见@MatteoTassinari答案,因为您可以将其标记为全局访问,但通常不需要全局变量,因此重新考虑编码是明智的。
menugen()
它的功能,这意味着要完成的工作不仅仅是生成菜单。例如,如何扩展菜单以从其他来源添加更多项目,以及如何选择菜单中当前选定的页面。到处都是随机的全局变量和逻辑,这为OOP设计大声疾呼。不需要构造PHP / JS的事实是您发现许多混乱的笨拙代码的最大原因之一。它可以做得很好,但是却使人们不必考虑未来的可维护性。
另一种方法是:
<?php
$data = 'My data';
$menugen = function() use ($data) {
echo "[".$data."]";
};
$menugen();
2020年1月13日更新:彼得·莫滕森的要求
从PHP 5.3.0开始,我们提供了可以创建闭包的匿名函数支持。闭包可以访问在其范围之外创建的变量。
在示例中,闭包能够访问,$data
因为它是在use
子句中声明的。
多年以来,我一直使用这种格式:
<?php
$data = "Hello";
function sayHello(){
echo $GLOBALS["data"];
}
sayHello();
?>
我发现它简单易懂。$ GLOBALS是PHP允许您引用全局变量的方式。如果您使用过$ _SERVER,$ _ POST等,那么您将引用全局变量而不知道它。
<?php
$data = 'My data';
$menugen = function() use ($data) {
echo "[ $data ]";
};
$menugen();
?>
您也可以简化
echo "[" . $data . "]"
至
echo "[$data]"
echo "[" . $data . "]"
和echo "[ $data ]"
不相同(后者的输出中有两个额外的空格)。