views:

47

answers:

4

I have a command interpreter in php. It lives inside the commands directory and needs access to every command in the command file. Currently I call require once on each command.

require_once('CommandA.php');
require_once('CommandB.php');
require_once('CommandC.php');

class Interpreter {
    // Interprets input and calls the required commands.
}

Is there someway to include all of these commands with a single require_once? I have a similar problem many other places in my code (with factories, builders, other interpreters). There is nothing but commands in this directory and the interpreter needs every other file in the directory. Is there a wildcard that can be used in require? Such as:

require_once('*.php');

class Interpreter { //etc }

Is there any other way around this that doesn't involve twenty lines of include at the top of the file?

+1  A: 

You can include all files using foreach ()
Store all files name in array.

$array =  array('read','test');

foreach ($array as $value) {
    include_once $value.".php";
}
Oyeme
+5  A: 
foreach (glob("*.php") as $filename) {
    require_once $filename;
}

I'd be careful with something like that though and always prefer "manually" including files. If that's too burdensome, maybe some refactoring is in order. Another solution may be to autoload classes.

deceze
What's the danger in doing something like the above glob?
Daniel Bingham
@Daniel: There's a big chance you'll require a lot of sources that will be unused.
fabrik
It opens you up to security vulnerabilities if somebody is able to place a .php file in one of the include directories, possibly through exploiting another vulnerability somewhere. It also makes it harder to keep track of what's included where.
deceze
@daniel: I'd try to only include the files needed contitionally. See my answer below.
thomasmalt
@fabrik Not likely here, the directory structure is designed such that this directory contains only the command files used by this interpreter. No more, no less.
Daniel Bingham
@deceze Fair enough.
Daniel Bingham
+1  A: 

You can't require_once a wildcard, but you can programmatically find all the files in that directory and then require them in a loop

foreach (glob("*.php") as $filename) {
    require_once($filename) ;
}

http://php.net/glob

Fanis
+3  A: 

Why do you want to do that? Isn't it a better solution to only include the library when needing it to increase speed and reduce footprint?

Something like this:

Class Interpreter 
{
    public function __construct($command = null)
    {
        $file = 'Command'.$command.'.php';

        if (!file_exists($file) {
             throw new Exception('Invalid command passed to constructor');
        }
        include_once $file;

        // do whatever else you want here.
    }
}
thomasmalt
Bloody brilliant. Wouldn't have thought of that one - rather foolish of me, since my naming and directory structure is already set up to do exactly this. I just wouldn't have thought of conditionally including. Guess that's my old C mindset causing me problems again...
Daniel Bingham
An [autoload](http://de.php.net/manual/en/function.spl-autoload-register.php) solution would be somewhat more elegant though.
Gordon
I agree, but only if the code inside each Command<Foo>.php is object oriented though.
thomasmalt