您能在不使用全局变量的情况下将值传递给PHP中包含的文件吗?

您能在不使用全局变量的情况下将值传递给PHP中包含的文件吗?,php,include,global-namespace,Php,Include,Global Namespace,我在PHP中经常使用的一种模式是设置一些全局变量(例如$page,$user,$db,等等),然后包括一个使用这些全局变量的文件。不过,我从来都不喜欢使用globals来实现这一点,所以我正在寻找一种更好的方法 显而易见的解决方案是在子文件中定义一个类或函数,并在包含该文件后调用它。但在某些情况下,这是行不通的,例如: // Add entries to a URI table from each section of the site global $router; $router = new

我在PHP中经常使用的一种模式是设置一些全局变量(例如
$page
$user
$db
,等等),然后包括一个使用这些全局变量的文件。不过,我从来都不喜欢使用globals来实现这一点,所以我正在寻找一种更好的方法

显而易见的解决方案是在子文件中定义一个类或函数,并在包含该文件后调用它。但在某些情况下,这是行不通的,例如:

// Add entries to a URI table from each section of the site
global $router;
$router = new VirtualFileSystem();
$sections = array('store', 'forum', 'blog');
foreach($sections as $section)
    include dirname(__FILE__) . $section . '/routing.php';

// Example contents of 'forum/routing.php'
// implicitly receive $router from caller
$router->add('fourm/topic/', 'topic.php');
$router->add('forum/topic/new/', 'new_topic.php');
// etc
如果我试图将每个
routing.php
封装在一个函数中,并使用
$router
作为参数调用它们,那么在多个文件中定义相同的函数名后,它们会发生冲突


我没有主意了。有没有更好的方法可以在不污染全局命名空间的情况下将变量传递到包含的文件?

include
及其同级基本上只是复制粘贴帮助程序,它们内部的代码与调用块共享作用域-就好像您要将其复制粘贴到
include
语句所在的位置一样。使用它们的明智方法是用与在C中使用
\include
或在C中使用
或在Java中使用
import
相同的方式来考虑它们:导入一些代码以供以后参考。如果包含的文件中有需要参数的代码,则将其包装在函数中,将参数放入函数参数中,在包含文件的顶部使用一次
include\u
,然后在需要的任何位置使用所需参数调用函数。不需要全局。根据经验,在常规操作中,最好避免将任何“执行”操作(在全局范围内执行语句)的代码放入包含的文件中。

include
及其同级基本上只是复制粘贴帮助程序,它们内部的代码与调用块共享作用域——就好像您要将它复制并粘贴到
include
语句所在的位置一样。使用它们的明智方法是用与在C中使用
\include
或在C中使用
或在Java中使用
import
相同的方式来考虑它们:导入一些代码以供以后参考。如果包含的文件中有需要参数的代码,则将其包装在函数中,将参数放入函数参数中,在包含文件的顶部使用一次
include\u
,然后在需要的任何位置使用所需参数调用函数。不需要全局。根据经验,在常规操作中,最好避免将任何“执行”操作(在全局范围内执行语句)的代码放入包含的文件中。

不,没有。无论如何,您都不会将变量传递给包含的文件。包含的代码的行为就像是在编写
include
语句的地方编写的一样。因此,您没有将变量传递到包含的文件中,文件中的代码可以简单地使用
include
语句所在范围内的变量

在您的例子中,
forum/routing.php
的内容并不是真正独立的代码,它们是依赖于一个非常特别的设置范围来正确运行的代码片段。那太糟糕了。您应该以一种不会将可包含文件与包含代码耦合的方式编写可包含文件。例如,您可以将路由器设置为静态类,并在
forum/routing.php
中静态调用它:

require_once 'virtual_file_system.class.php';
VirtualFileSystem::add('forum/topic/', 'topic.php');

只要你的应用程序中有一个类
VirtualFileSystem
,它就可以工作,而且不会像现在这样污染名称空间。

不,没有。无论如何,您都不会将变量传递给包含的文件。包含的代码的行为就像是在编写
include
语句的地方编写的一样。因此,您没有将变量传递到包含的文件中,文件中的代码可以简单地使用
include
语句所在范围内的变量

在您的例子中,
forum/routing.php
的内容并不是真正独立的代码,它们是依赖于一个非常特别的设置范围来正确运行的代码片段。那太糟糕了。您应该以一种不会将可包含文件与包含代码耦合的方式编写可包含文件。例如,您可以将路由器设置为静态类,并在
forum/routing.php
中静态调用它:

require_once 'virtual_file_system.class.php';
VirtualFileSystem::add('forum/topic/', 'topic.php');

只要你的应用程序中有一个类
VirtualFileSystem
,它就可以工作,而且不会像现在这样污染名称空间。

你可以尝试一种面向对象的方法,将配置类设置为单例,并在需要时检索它

您可以为uuu get和uuu set定义神奇的方法,将它们添加到私有数组var中,并使构造函数私有

我通常只将src项目的路径定义为常量,以便快速正确地加载类文件(并使用一些SPL)


但我同意@tdammers的观点,即include会保留环境变量,就像您在调用方文件(创建include的人)上一样。

您可以尝试一种面向对象的方法,将配置类创建为单例,并在需要时检索它

您可以为uuu get和uuu set定义神奇的方法,将它们添加到私有数组var中,并使构造函数私有

我通常只将src项目的路径定义为常量,以便快速正确地加载类文件(并使用一些SPL)


但我同意@tdammers的观点,即include会保留环境变量,就像您在调用方文件(创建include的人)上一样。

只需在函数中隔离include:

function add_entries_to_router($router, $sections) {
    foreach($sections as $section)
        include dirname(__FILE__) . $section . '/routing.php';
}

$router = new VirtualFileSystem();
add_entries_to_router($router, array('store', 'forum', 'blog'));

仅隔离函数中的包含项:

function add_entries_to_router($router, $sections) {
    foreach($sections as $section)
        include dirname(__FILE__) . $section . '/routing.php';
}

$router = new VirtualFileSystem();
add_entries_to_router($router, array('store', 'forum', 'blog'));

看起来您过度复杂了
global$router
在那里什么都做不了,作用域已经是全局的(除非它写在一个我们没有看到的函数中)。看起来您过度复杂了
global$router
在那里什么都做不了,作用域