有没有办法将require_once()的范围显式设置为全局?

时间:2012-01-23 15:02:17

标签: php scope global-variables require-once

我正在寻找一种方法,在函数内部使用require_once()时,将require_once()的范围设置为全局范围。像下面的代码应该工作:

文件`foo.php':

<?php

$foo = 42;

实际代码:

<?php

function includeFooFile() {
    require_once("foo.php"); // scope of "foo.php" will be the function scope
}

$foo = 23;

includeFooFile();
echo($foo."\n"); // will print 23, but I want it to print 42.

有没有办法明确设置require_once()的范围?有一个很好的解决方法吗?

7 个答案:

答案 0 :(得分:5)

除了“全局化”你的变量之外,没有办法做到这一点:

global $foo;
$foo = 42;

OR

$GLOBALS['foo'] = 42;

然后打印时你的值应为42。

<强>更新

关于包含类或函数,请注意除非我们讨论类方法,否则所有函数和类始终被视为全局。此时,类中的方法只能从类定义本身获得,而不能作为全局函数。

答案 1 :(得分:3)

您需要在foo.php中声明全局:

<?php
 global $foo;
 $foo = 42;
?>

否则可能无法实现。

您可以尝试以各种组合方式使用extract()get_defined_vars()global$GLOBALS ...就像遍历所有已定义的变量并调用全局变量一样他们在要求文件之前......

$vars = get_defined_vars();
foreach($vars as $varname => $value)
{
  global $$varname; //$$ is no mistake here
}
require...

但是我不确定你是否到达了你想去的地方......

答案 2 :(得分:3)

这肯定是一个“好”的工作,但它会起作用:

function includeFooFile() {
  require_once("foo.php");
  foreach (get_defined_vars() as $key => $value) {
    // Ignore superglobals
    if (!in_array($key, array('GLOBALS','_SERVER','_GET','_POST','_FILES','_COOKIE','_SESSION','_REQUEST','_ENV'))) {
      $GLOBALS[$key] = $value;
    }
  }
}

但是,你所包含的文件不能定义任何函数或类(也可能是我目前无法想到的其他一些东西),因为它会导致解析错误,因为你不能嵌套类或函数。

编辑显然您可以在文件中包含功能。我一直认为你不能但经过测试后似乎可以。

答案 3 :(得分:2)

由于在使用require之类的地方明确定义了范围,您需要指定如何处理函数范围内的变量:

function includeFooFile() {
    require_once("foo.php"); // scope of "foo.php" will be the function scope

    foreach (get_defined_vars() as $k => $v)
    {
        $GLOBALS[$k] = &$v;
    }
}

这个例子处理你​​可能正在寻找的变量和引用。 Demo。请注意,require_once只能使用一次,并且只会定义一次变量。

答案 4 :(得分:1)

根据您的具体要求,您可以使用constants。要求您的文件在全局范围内,但在其中设置一个常量。

IE file.php:

define('MY_CONSTANT', 42);

然后,您的脚本中的任何地方只需使用MY_CONSTANT来引用该值,但一旦设置完毕,您将无法进行编辑。除此之外,您可以像其他答案所说的那样全局化您的变量,但除了从包含的文件中检索值之外,您不是100%清楚您要实现的目标吗?在这种情况下,常数应该没问题。

<强>更新 现在您已经解释过您希望对象属性随处可用,我建议您考虑创建一个static class,一旦在您的全局范围内实例化,就可以在您的应用中的任何位置使用。阅读链接的手册页,它有一个简单的例子。

答案 5 :(得分:1)

我没有尝试过(因为使用全局变量是一个坏主意)但这可能有用:

require_once '...';
$GLOBALS = array_merge($GLOBALS, get_defined_vars());

或者你也可以手动完成:

foreach (get_defined_vars() as $k => $v) {
    $GLOBALS[$k] = $v;
}

答案 6 :(得分:1)

你可以使用我写的这个hacky函数:

/**
 * Extracts all global variables as references and includes the file.
 * Useful for including legacy plugins.
 *
 * @param string $__filename__ File to include
 * @param array  $__vars__     Extra variables to extract into local scope
 * @throws Exception
 * @return void
 */
function GlobalInclude($__filename__, &$__vars__ = null) {
    if(!is_file($__filename__)) throw new Exception('File ' . $__filename__ . ' does not exist');
    extract($GLOBALS, EXTR_REFS | EXTR_SKIP);
    if($__vars__ !== null) extract($__vars__, EXTR_REFS);
    unset($__vars__);
    include $__filename__;
    unset($__filename__);
    foreach(array_diff_key(get_defined_vars(), $GLOBALS) as $key => $val) {
        $GLOBALS[$key] = $val;
    }
}

当包含文件返回时,它会将任何新定义的变量移回全局空间。需要注意的是,如果包含的文件包含另一个文件,它将无法通过$GLOBALS访问父文件中定义的任何变量,因为它们还没有全球化。 / p>