开发者

Can you pass values to included files in PHP without using globals?

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/', 'topi开发者_Go百科c.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?


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.


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.


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


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜