有没有办法将require_once()的作用域显式设置为global



当函数内部使用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()范围的方法?有没有一个好的变通办法?

除了"全球化"变量之外,没有办法做到这一点:

global $foo;
$foo = 42;

$GLOBALS['foo'] = 42;

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

更新

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

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

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

否则,这可能是不可能的。

你可以试着用extract()get_defined_vars()global$GLOBALS进行各种组合,也许。。。比如遍历所有定义的变量,并在需要文件之前对其调用global。。。

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

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

这绝对不是一个"不错"的解决方案,但它会起作用:

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;
    }
  }
}

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

EDIT显然您可以在文件中包含函数。我一直认为你做不到,但经过测试,似乎你可以。

由于范围是在使用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只工作一次,并且只定义变量一次。

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

/**
 * 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;
    }
}

当include文件返回时,它会将任何新定义的变量移回全局空间。需要注意的是,如果包含的文件包括另一个文件,它将无法通过$GLOBALS访问父文件中定义的任何变量,因为这些变量尚未全球化。

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

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

或者你也可以手动操作:

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

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

IE文件.php:

define('MY_CONSTANT', 42);

然后,在脚本中的任何地方,只要使用MY_CONSTANT来引用该值,一旦设置好,就无法进行编辑。除此之外,你可以像另一个答案所说的那样全球化你的变量,但除了简单地从包含的文件中检索一个值之外,你还不能100%清楚你想要实现什么?在这种情况下,常数应该很好。

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

相关内容

  • 没有找到相关文章