Some Newbie
Some Newbie

Reputation: 1079

PHP dependency and classpath management

One thing that often troubles me is that I don't have a class path and dependency management system in PHP. Is there a framework you can suggest? I heard Pear is a good system to look into but I'd like to know what else is there.

An example would be say... I have files A.php, B.php, and C.php where A depends on B who depends on C. where all 3 are in different folders.

So once A.php includes B.php, it also needs to include C.php. Typing require_once("C.php") in B.php wouldn't work because the require_once has to call a relative path between A.php and C.php and not between B.php and C.php, which is annoying.

Upvotes: 0

Views: 1269

Answers (3)

db80
db80

Reputation: 4427

I suggest you to try the doctrine class loader project.

Here you can find the official documentation.

In order to use this library, you need a version of php that has the namespace support (then >= 5.3)

Upvotes: 2

fd8s0
fd8s0

Reputation: 1927

Composer is where it's all going, and it does all this for you quite handily

http://getcomposer.org/

Upvotes: 1

kniteli
kniteli

Reputation: 530

For this problem I tend to prefer an autoloader. It's not hard to make a robust script to scan some given files and build a list of classes mapped to files out of them. Here's how I do it:

$classes = array();

//this is the main function, give it a file and it will map any
//classes it finds in the file to the path. How you find the files
//is up to you, only you know your directory structure, but I
//generally set up a few folders that hold my classes, and have
//the script recurse through those passing each file it finds through
//this function
function get_php_classes($file) {
    global $classes;
    $php_code = file_get_contents($file);
    $tokens = token_get_all($php_code);
    $count = count($tokens);

    //uses phps own parsing to figure out classes
    //this has the advantage of being able to find
    //multiple classes contained in one file
    for ($i = 2; $i < $count; $i++) {
        if (   $tokens[$i - 2][0] == T_CLASS
            && $tokens[$i - 1][0] == T_WHITESPACE
            && $tokens[$i][0] == T_STRING) {

            $class_name = $tokens[$i][1];
            //now we map a class to a file ie 'Autoloader' => 'C:\project\Autoloader.cls.php'
            $classes[$class_name] = $file;
        }
    }
}

$fh = fopen('file_you_want_write_map_to', 'w');
fwrite($fh, serialize($classes));
fclose($fh);

That's the script that generates the file mappings, you run it once anytime you add a new class. Here is the actual application code that can be used to autoload:

class Autoloader {
    private $class_map;

    public function __construct() {

        //you could also move this out of the class and pass it in as a param
        $this->class_map = unserialize(file_get_contents($file_you_wrote_to_earlier));
        spl_autoload_register(array($this, 'load'));
    }

    private function load($className) {
        //and now that we did all that work in the script, we
        //we just look up the name in the map and get the file
        //it is found in
        include $this->class_map[$className];
    }
}

There's a lot more that could be done with this, namely safety checking for various things such as duplicate classes found while building the autoload list, making sure that files exist before trying to include them, etc.

Upvotes: 3

Related Questions