2010-10-03 94 views
1

所以senario是我想要一个自定义函数来需要库。喜欢的东西:PHP中全局命名空间的运行功能块

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,因为它是这么多的主机被禁止。)

谢谢!

+0

如果它真的是*库*,而不是模块,那么它包含在 – 2010-10-03 15:00:18

+0

中的范围并不重要,这是什么意思? – 2010-10-03 15:03:15

+0

我的意思是图书馆通常只代表一个包含函数/类的文件 – 2010-10-03 16:05:31

回答

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()调用。因此,通过我之前提供的脚本,您应该需要将全局范围拉到您的变量中。

0
require_once E_ROOT.$libName.'.php'; 

KISS

+0

我只希望libName不是来自用户输入 – 2010-10-03 14:58:52

+0

我的意思是$ libName来自函数。并且,是的—这个工作。但对于说10个不同的文件,这是很多不重复的文件。 – 2010-10-03 15:03:08

+0

与'e_load('libName')'对比。 – 2010-10-03 15:23:19

0

而不是做这个的......

$test = "Hello, World!"; 

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

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

在本地函数上下文和全局包含上下文中安全且一致。从视觉上提醒读者,您希望$测试成为全球化可能无害。如果你有大量的全局变量被你的库拖入,也许有理由将它包装在一个类中(然后你有spl_autoload_register的好处,无论如何你会做什么)。