【问题标题】:PHP - strange global behaviorPHP - 奇怪的全局行为
【发布时间】:2014-03-08 21:05:16
【问题描述】:

我正在尝试从所需文件中定义的函数访问变量:

**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 似乎是 NULL。 我也试过这个来调试:

**function.php

var_dump($test);
function fn() {
    global $test;
    return $test;
}

var_dump() 返回正确的值...我该如何解决这个问题?

【问题讨论】:

  • 简单修复:不要使用全局变量。而是将这些变量传递给参数。
  • 您不是在global 范围 中定义$test,而是在run() 函数的范围 中定义它,所以使用global是没有意义的
  • 为什么 var_dump 返回 'Var!'?
  • 因为您将 function.php 与该 var_dump() 包含在 run() 函数的范围内,并且 $test 在该函数的范围内
  • 所以总而言之我可以使用匿名函数来成功......好吧

标签: php function include global-variables


【解决方案1】:

为什么它不起作用?

function run() {
    require('cfg.php');
    require('function.php');
    print(fn());
}

您的代码存在variable scope 问题。 cfg.phpfunction.php 中的变量/函数只存在于 run() 函数中,不能全局访问。

考虑您的fn() 函数:

function fn() {
    global $test;
    return $test;
}

您正在尝试访问 $test 变量。它不是全局定义的,因此尝试访问它会返回NULL(应该如此)。

考虑第二种情况:

$test = 'Var!';

var_dump($test);

function fn() {
    global $test;
    return $test;
}

在这里,$test 变量被定义。所以global $test;变量会正确地将变量导入到函数作用域中,return语句会返回变量。这就解释了为什么你会得到第二个代码块的输出 Var!

你应该改用什么?

使用global 变量不被认为是好的做法,因为它违反了封装等。我建议不要使用它们。

使用常量来存储配置。常量的范围是全局。您可以在脚本中任何地方访问常量,而无需考虑范围。

将您的逻辑分成多个文件。 使用cfg.php 进行配置,使用functions.php 进行功能等。这样,您可以独立保存文件并根据需要使用一个。这样,您还可以避免必须从包含的文件中包含(甚至,从包含的文件中包含的包含)等问题。


config.php

<?php

define('test', 'Var!')

functions.php:

<?php

function doSomething($foo) {
    // do something with $foo and return
}

function somethingElse($bar) {
    // do something with $bar and return
}

main.php:

<?php

require_once 'cfg.php';
require_once 'include.php';

// more code

【讨论】:

  • 哦,我表达错了,我不需要静态变量...变量包含对象,所以定义对我不起作用..
  • @IgelHaut:这只是一个例子。原理还是一样的。不要试图把所有东西都塞进一个函数中。这不是一个好主意。
  • 问题是,我打算用不同的文件编写可扩展的代码,有时我需要访问“cfg.php”中的对象(在这个例子中)。所以现在我正在考虑在包含的文件中使用匿名函数
【解决方案2】:

您将cfg.php 包含在run 函数的上下文中——因此,变量定义创建了一个局部变量。

如果您将$test = 'Var!' 更改为$GLOBALS['test'] = 'Var!',您将获得预期的行为,但是虽然这会使问题消失,但它不是一种好方法——将变量从一个脚本注入另一个作用域永远不会。

您可能应该做的是使用constants,例如:

// cfg.php
const TEST = 'Var!';

// main.php
require('cfg.php');

function run() {
    require('function.php');
    print(fn());
}

// function.php

function fn() {
    return TEST;
}

【讨论】:

  • -1:这是一个非常糟糕的主意。每次调用该函数时,您都会requireing 文件。
  • @AmalMurali:鉴于这是一个抽象的例子,我不太同意这种非常具体的批评。你怎么知道一个名为run 的函数会被多次调用?如果我把它改成require_once,你会满意吗?
  • 我知道这是一个抽象的例子,但我认为这不是一个好的做法,@Jon,仅此而已。关于被多次调用的函数:我没有。这才是重点。如果我不知道该函数将被调用多少次,我为什么要允许这种可能性?不,我不认为require_once() 是解决这个问题的正确方法:)
  • @AmalMurali: require_once 不是正确的方法吗?这就是它的用途。如果从未调用过run,你怎么知道function.php 甚至应该包含在内?
猜你喜欢
  • 2016-08-24
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-08
  • 2013-08-09
  • 2021-11-21
相关资源
最近更新 更多