您可以在不使用全局变量的情况下将值传递给 PHP 中包含的文件吗?
我在 PHP 中经常使用的一种模式是设置一些全局变量(例如 $page
、$user
、$db
等),然后包含一个使用这些全局变量的文件。不过,我从来不喜欢使用全局变量的想法,所以我正在寻找更好的方法。
显而易见的解决方案是在子文件中定义一个类或函数,并在包含文件后调用它。但在某些情况下,这是行不通的,例如:
// 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
作为调用它们参数,相同的函数名称在多个文件中定义后会发生冲突。
我没主意了。有没有更好的方法将变量传递到包含的文件而不污染全局名称空间?
A pattern I tend to use often in PHP is setting a few globals (such as $page
, $user
, $db
, etc), and then including a file which uses those globals. I've never liked the idea of using globals for this, though, so I'm looking for a better way.
The obvious solution is to define a class or function in the subfile, and call it after the file is included. There are cases where that can't work though, such as this:
// 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
If I tried to wrap each routing.php
in a function and call them each with $router
as an argument, the same function name would clash after being defined in multiple files.
I'm out of ideas. Is there a better way to pass variables to included files without polluting the global namespace?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
include
及其同级基本上只是复制粘贴助手,它们内部的代码与调用块共享作用域 - 就像您复制并粘贴一样。将其粘贴到include
语句所在的位置。使用它们的明智方法是将它们视为与在 C 中使用#include
或在 C# 中使用using
或在Java:导入一些稍后参考的代码。如果包含文件中有需要参数的代码,则将其包装在函数中,将参数放入函数参数中,在包含文件顶部使用include_once
,然后使用随时随地提供您想要的参数。不需要全局变量。根据经验,在常规操作中,最好避免将任何“执行”某些操作(在全局范围内执行语句)的代码放入包含的文件中。include
and its siblings are basically just copy-paste helpers, and the code inside them shares scope with the calling block - as if you'd copy & paste it just where theinclude
statement is. The sane way of using them is to think of them the same way you'd use#include
in C orusing
in C# orimport
in Java: import some code to be referenced later on. If you have code in the included file that needs parameters, then wrap it in a function, put the parameters in the function arguments, useinclude_once
at the top of the including file, and call the function with the parameters you want, wherever you need to. No globals required. As a rule of thumb, in regular operation, putting any code that "does" something (executes statements in the global scope) in an included file is best avoided IMO.不,没有。无论如何,您都不会将变量传递给包含的文件。包含的代码的行为就好像它是在
include
语句所在的位置编写的。因此,您不会将变量传递到包含的文件中,文件中的代码可以简单地使用include
语句所在范围内的变量。在您的情况下,
forum/routing.php
的内容并不是真正的独立代码,它们是依赖于非常具体设置的范围才能正确运行的代码片段。那很糟糕。您应该以不将可包含文件与包含代码耦合的方式编写它们。例如,您可以将 Router 设为静态类并在forum/routing.php
中静态调用它:只要您的应用程序中有一个类
VirtualFileSystem
,这就会工作,并且不会比现在更污染命名空间。No, there is not. You're not passing variables to included files anyway. The code that is included behaves as if it was written where the
include
statement is written. As such, you're not passing variables into the included file, the code in the file can simply use the variables that are in scope wherever theinclude
statement is located.In your case the contents of
forum/routing.php
are not really standalone code, they're code snippets that depend on a very specifically set up scope to function correctly. That's bad. You should write your includable files in a way that does not couple them to the including code. For example, you could make your Router a static class and call it statically inforum/routing.php
:As long as there is a class
VirtualFileSystem
in your app, this will work, and won't pollute the namespace any more than it already is anyway.只是隔离包含在函数中:
just isolate includes in a function:
您可以尝试 OOP 方式,将 Configuration 类作为单例并在需要时检索它。
您可以为 __get 和 __set 定义魔术方法,将它们添加到私有数组 var 并使构造函数私有。
我通常只将 src 项目的路径定义为常量,以便快速正确地加载类文件(也使用一些 SPL)。
但我同意 @tdammers 的观点,即包含保留环境变量,就像您在调用者文件(制作包含的文件)中一样。
You can try an OOP way by making a Configuration class as a singleton and retrieving it when you need it.
You could define magic methods for __get and __set to add them to an private array var and make the constructor private.
I usually define as constant only the path to my src project in order to load class files quickly and properly (and use some SPL too).
But I agree with @tdammers about the fact that an include keep the environment variables like if you were on the caller file (the one who makes the include).