views:

107

answers:

3

I was just learning aboutt PHP namespaces and starting to create a simple autoload function. What O did was:

function __autoload($name) {
  echo $name . "<br />";
  require_once $name . ".php";
}

So, this works if I do not use any aliasing or importing statements eg. use MainNamespace\Subnamespace because if I did that, assuming i have:

\GreatApp\Models\User.php
\GreatApp\Models\Project.php
\GreatApp\Util\Util.php
\GreatApp\Util\Test\Test.php

if I try to do:

new GreatApp\Models\User();

it works because $name in autoload will become GreatApp\Models\User so GreatApp\Models\User.php is found. But when I do:

use GreatApp\Models;
new User();

it fails because now $name is just User and User.php will not be found. How should I setup autoloading then?

A: 

Try using:

if(file_exists('directory1/'.$name)) require_once('directory1/'.$name.'.php'));
elseif(file_exists('directory2/'.$name)) require_once('directory2/'.$name.'.php'));
...

This way you can use multiple directories in autoload.

cypher
While this technically solves the problem, it has the detriment of requiring hard coding for EVERY PACKAGE.
Christopher W. Allen-Poole
This provides a solution. I'm not saying it is a great one, but it solves the problem. Try posting a better solution then.And on the other hand, you can always scan all directories in the root class directory with a script and then look for them, this way you won't have to hard code anything.
cypher
+1  A: 

Full namespace path is always passed to the autoloader no matter how you import namespace and reference a class. It should work.

Just the __autoload function itself should belong to main (root) namespace

FractalizeR
when i try `use GreatApp\Util; new Test\Test;` `$name` in `__autoload()` echos out `Test\Test` and the autoload fails with `require_once(Test\Test.php): failed to open stream`
jiewmeng
Please read PHP docs on how namespaces work. When you try to reference a class using "Test\Test" it actually means you a referencing \current-namespace\Test\Test. current-namespace is the namespace of the file from where you are referencing. "use" does not change current namespace. It just imports another namespace to use from within current.
FractalizeR
A: 

The best way is to name your Classes like:

class GreatApp_Models_User() {}

so you can set:

$user = new GreatApp_Models_User();

and autoload:

function __autoload( $name )
{
    $name = str_replace( '_', '\', $name );
    require_once( $name . ".php" );
}

not GreatApp_Models_User will change to GreatApp\Models\User.php, and this is found ;)

This is the way most MVC Frameworks are working... And me too :)

ahmet2106
i know abt this, but assuming i want to use the 5.3 namespace support thats available?
jiewmeng