我怎样才能模仿PHP疯狂的全局事物?

时间:2013-02-03 11:03:05

标签: php global-variables

如果我有一个我无法编辑的文件a.php

<?php
$a = 1;
function a() {
  global $a;
  echo $a;
}  
a();

然后运行php a.php很好地打印1。但如果我有b.php

<?php
function b() {
  include "a.php";
}
b();

然后运行php b.php不会打印任何内容。

我可以在include "a.php"之前键入哪些内容,以便在不编辑a.php的情况下使其行为相同?

(显然除了定义$a之外。在我的真实世界的例子中,它必须适用于复杂的a.php)。

3 个答案:

答案 0 :(得分:3)

尝试在新功能中添加全局:

function b() {
  global $a;

  include "a.php";
}

目前我想知道PHP是否将$a视为您b()函数的本地。

附录:在回复您的评论时,您似乎需要获取您的包在您的函数中本地创建的任意变量,并将它们重新设置为全局变量。这适用于OSX 10.6.8上的5.3.20:

function b() {
    include 'a.php';

    // Move variables into global space
    foreach (get_defined_vars() as $name => $value) {
        global $$name;
        // global wipes the value, so just reset it
        $$name = $value;
        echo "Declared $name as global\n";
    }
}

b();
// Your global vars should be available here

显然,一旦您感到满意,就可以删除echo

答案 1 :(得分:2)

在函数内定义函数?呸。但我猜你有一个现实世界的情况,不允许任何其他方式。但是为了记录,这真的很糟糕

global $a添加到b()应该有效。

function b() {
  global $a;
  include "a.php";
}
  

我不知道需要定义哪些变量。 a.php真的很复杂

然后我能想到的唯一方法就是不在b.php中使用函数,因此在包含a.php时你处于全局范围。我别无他法。

答案 2 :(得分:1)

听起来a.php是您必须在自己的应用程序中包装的遗留或第三方脚本。我有一个类似的问题,解决方案并不漂亮。首先,您将必须找出存在的全局变量(grep global或类似的帮助)。

这是我的“脚本适配器”类的相关部分:

private function _includeScript($file, $globals)
{
    foreach ($globals as $global) {
        global $$global;
    }

    ob_start();
    require $file;
    $this->_response->setBody(ob_get_clean());
}

如你所见,我也必须抓住输出。该类还模拟$_GET并捕获header调用以将所有内容分配给Response对象,但对于您的情况,只有此方法很重要。它将使用文件名和全局变量名称数组作为参数进行调用:

_includeScript('a.php', array('a'));