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

发布于 2024-10-07 23:32:49 字数 825 浏览 3 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

归途 2024-10-14 23:32:49

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 the include statement is. The sane way of using them is to think of them the same way you'd use #include in C or using in C# or import 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, use include_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.

冰火雁神 2024-10-14 23:32:49

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

在您的情况下,forum/routing.php 的内容并不是真正的独立代码,它们是依赖于非常具体设置的范围才能正确运行的代码片段。那很糟糕。您应该以不将可包含文件与包含代码耦合的方式编写它们。例如,您可以将 Router 设为静态类并在 forum/routing.php 中静态调用它:

require_once 'virtual_file_system.class.php';
VirtualFileSystem::add('forum/topic/', 'topic.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 the include 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 in forum/routing.php:

require_once 'virtual_file_system.class.php';
VirtualFileSystem::add('forum/topic/', 'topic.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.

心碎的声音 2024-10-14 23:32:49

只是隔离包含在函数中:

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'));

just isolate includes in a function:

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'));
简单爱 2024-10-14 23:32:49

您可以尝试 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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文