在PHP中的全局命名空间的上下文中运行功能块

时间:2010-10-03 14:51:41

标签: php file

所以senario是我想要一个自定义函数来要求库。类似的东西:

define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {
    $inc = E_ROOT.'/path/here/'.$fn.'.php';
    if($allowReloading)
        require $inc; // !!!
    else
        require_once $inc; // !!!
}

问题是requirerequire_once会将文件加载到函数的命名空间中,这对函数库,类等没有帮助。有没有办法做到这一点?

(完全避免requirerequire_once的内容很好,只要它不使用eval,因为它在很多主机上被禁止。)

谢谢!

3 个答案:

答案 0 :(得分:2)

从技术上讲,include()的作用就像是在PHP中插入包含脚本的文本一样。因此:

includeMe.php:
<?php
    $test = "Hello, World!";
?>

includeIt.php:
<?php
    include('includeMe.php');
    echo $test;
?>

应与:

完全相同
<?php
    /* INSERTED FROM includeMe.php */
    $test = "Hello, World!";
    /* END INSERTED PORTION */
    echo $test;
?>

意识到这一点,为动态包含文件制作函数的想法与将动态代码整合在一起具有同样的意义(并且很容易做到)。这是可能的,但它会涉及很多元变量。

我将在PHP中查看Variable Variables以及将变量引入全局范围的get_defined_vars函数。这可以通过以下方式完成:

<?php
define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {

    $prev_defined_vars = get_defined_vars();

    $inc = E_ROOT.'/path/here/'.$fn.'.php';
    if($allowReloading)
        require $inc; // !!!
    else
        require_once $inc; // !!!

    $now_defined_vars = get_defined_vars();

    $new_vars = array_diff($now_defined_vars, $prev_defined_vars);

    for($i = 0; $i < count($new_vars); $i++){
        // Pull new variables into the global scope
        global $$newvars[$i];
    }
}
?>

使用require()require_once()代替e_load()

可能会更方便

请注意,函数和常量应该始终位于全局范围内,因此无论它们在何处定义,都应该可以从代码中的任何位置调用它们。

这个例外是一个类中定义的函数。这些只能在类的名称空间中调用。

编辑:

我自己测试了这个。函数在全局范围内声明。我运行了以下代码:

<?php
function test(){
    function test2(){
        echo "Test2 was called!";
    }
}

//test2(); <-- failed
test();
test2(); // <-- succeeded this time
?>

因此该函数仅在test()运行后定义,但该函数可以从test()之外调用。因此,通过我之前提供的脚本,您唯一需要进入全局范围的是变量。

答案 1 :(得分:0)

require_once E_ROOT.$libName.'.php';

KISS

答案 2 :(得分:0)

而不是这样做......

$test = "Hello, World!";

......你可以考虑这样做......

$GLOBALS[ 'test' ] = "Hello, World!";

在本地函数上下文和全局包含上下文中哪些是安全且一致的。可能没有害于视觉提醒读者你期望$ test成为全球性的。如果您的库中拖入了大量的全局变量,那么将它包装在一个类中是有道理的(那么你就有了spl_autoload_register的好处,无论如何你都在做什么)。