13

我正在寻找一种将范围设置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()?有没有很好的解决方法?

4

7 回答 7

5

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

global $foo;
$foo = 42;

或者

$GLOBALS['foo'] = 42;

那么当你打印出来时你的值应该是 42。

更新

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

于 2012-01-23T15:07:51.860 回答
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...

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

于 2012-01-23T15:11:34.370 回答
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;
    }
  }
}

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

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

于 2012-01-23T15:15:53.303 回答
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;
    }
}

此示例处理可能是您正在寻找的变量和引用。演示。请注意,require_once这只会工作一次,并且只会定义一次变量。

于 2012-01-23T15:15:06.177 回答
1

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

IE文件.php:

define('MY_CONSTANT', 42);

然后脚本中的任何地方都只是MY_CONSTANT用来引用该值,但一旦设置,您将无法编辑。除此之外,您可以像其他答案所说的那样全球化您的变量,但是除了简单地从包含的文件中检索一个值之外,您还试图实现什么并不是 100% 清楚?在这种情况下,常量应该没问题。

更新: 现在您已经解释说您希望对象属性在任何地方都可用,我建议您考虑创建一个静态类,一旦在您的全局范围内实例化,就可以在您的应用程序的任何地方使用。阅读链接的手册页,它有一个简单的例子。

于 2012-01-23T15:07:56.130 回答
1

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

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

或者,您可以手动进行:

foreach (get_defined_vars() as $k => $v) {
    $GLOBALS[$k] = $v;
}
于 2012-01-23T15:17:57.173 回答
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;
    }
}

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

于 2015-05-13T21:57:22.687 回答