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
变量。So
global$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