PHP-奇怪的全局行为
我试图从所需文件中定义的函数访问变量:PHP-奇怪的全局行为,php,function,include,global-variables,Php,Function,Include,Global Variables,我试图从所需文件中定义的函数访问变量: **main.php** function run() { require('cfg.php'); require('function.php'); print(fn()); } **cfg.php** $test = 'Var!'; **function.php** function fn() { global $test; return $test; } 我期望“Var!”作为输出。但是,$tes
**main.php**
function run() {
require('cfg.php');
require('function.php');
print(fn());
}
**cfg.php**
$test = 'Var!';
**function.php**
function fn() {
global $test;
return $test;
}
我期望“Var!”作为输出。但是,$test
似乎为空。
我还尝试了以下方法进行调试:
**function.php
var_dump($test);
function fn() {
global $test;
return $test;
}
var\u dump()
返回正确的值。。。如何修复此问题?您将cfg.php
包含在run
函数的上下文中——因此,变量定义创建了一个局部变量
如果更改$test='Var!',您将获得预期的行为代码>至$GLOBALS['test']='Var!'代码>,但尽管这会使问题消失,但这不是一种好的做法——将变量从一个脚本注入到另一个作用域永远都不是
您可能应该改为使用,例如:
为什么不起作用?
您的代码存在问题。cfg.php
和function.php
中的变量/函数只存在于run()
函数中,它们不能全局访问
考虑您的fn()
函数:
function fn() {
global $test;
return $test;
}
您正在尝试访问$test
变量。它不是全局定义的,因此尝试访问它将返回NULL
(应该如此)
考虑第二种情况:
$test = 'Var!';
var_dump($test);
function fn() {
global $test;
return $test;
}
这里定义了$test
变量。Soglobal$test
variable将正确地将变量导入函数范围,return语句将返回变量。这就解释了为什么要得到输出Var代码>用于第二个代码块
你应该用什么来代替?
使用global
变量被认为是不好的做法,因为它违反了封装等。我建议不要使用它们
使用常量存储配置。常量的范围是全局的。您可以在脚本中的任何位置访问常量,而不考虑范围
将逻辑分隔为多个文件。使用cfg.php
进行配置,使用functions.php
进行函数等。这样,您就可以独立保存文件,并根据需要使用一个文件。通过这种方式,您还可以避免从包含的文件(甚至从包含的文件的包含中包含)中包含等令人头痛的问题
config.php
<?php
define('test', 'Var!')
main.php:
<?php
function doSomething($foo) {
// do something with $foo and return
}
function somethingElse($bar) {
// do something with $bar and return
}
<?php
require_once 'cfg.php';
require_once 'include.php';
// more code
Easy fix:不要使用全局变量。将这些变量改为传递参数。您不是在global
范围内定义$test
,而是在run()
函数的范围内定义它,因此使用global
是没有意义的,为什么var\u dump返回“var!”?因为您在run()
函数的作用域中包含function.php和var_dump(),并且$test在该函数的作用域中,所以总之,我可以使用匿名函数来成功。。。好的-1:这是一个非常糟糕的主意。每次调用函数时,您都将要求
对文件进行加密。@AmalMurali:鉴于这是一个抽象的示例,我不太同意这种非常具体的批评。您如何知道名为run
的函数将被多次调用?如果我将其更改为require\u once
,您会满意吗?我知道这是一个抽象的示例,但我认为这不是一个好的做法,@Jon,仅此而已。关于函数被多次调用:我没有。这就是重点。如果我不知道函数将被调用多少次,为什么我应该允许这种可能性?不,我不认为require\u once()
是解决这个问题的正确方法:)@AmalMurali:require\u once
不是正确的方法吗?这就是它的目的。如果从未调用run
,你怎么知道应该包括function.php
?哦,我表达错了,我不需要静态变量。。。变量包含object,因此define对我不起作用。@IgelHaut:这只是一个示例。原则仍然是一样的。不要试图将所有内容都塞进函数中。这不是一个好主意。问题是,我打算用不同的文件编写可扩展代码,有时我需要访问“cfg.php”(在本例中)中的对象。所以现在我考虑在包含的文件中使用匿名函数
<?php
function doSomething($foo) {
// do something with $foo and return
}
function somethingElse($bar) {
// do something with $bar and return
}
<?php
require_once 'cfg.php';
require_once 'include.php';
// more code