4

I've been playing a bit with the Symfony class loader (read about others, the concept and started implementing).

I've read http://symfony.com/doc/current/components/class_loader.html as well I've changed the directories structure to fit and all. Here's a small source-code which fails:

Filename: test.php , dir: C:/test/BE/src/main.php

   <?php
    define('BASE_DIR','/../..');

    echo BASE_DIR.'/BE/libs/symphony/component/ClassLoader/2.1.0/UniversalClassLoader.php';
    require_once BASE_DIR.'/BE/libs/symphony/component/ClassLoader/2.1.0/UniversalClassLoader.php';

    use Symfony\Component\ClassLoader\UniversalClassLoader;

    $loader = new UniversalClassLoader();
    $loader->registerNamespace('App\Location\Location', 'Location/Location');

     // You can search the include_path as a last resort.
    $loader->useIncludePath(true);    
    $loader->register();
    use App\Location\Location;
    new App\Location\Location(); //Fatal error: Class 'App\Location\Location' not found in C:/test/BE/src/main.php

file name: Location.php , dir: C:/test/BE/src/Location/Location.php

namespace App\Location;

class Location{
    private $lat;
    private $lng;
}
4
  • What is your error? Which information are you missing from the docs in concrete? (Asking for docs is somewhat broad, other people are missing other information). Commented Apr 29, 2012 at 9:33
  • I've wrote it as a comment in the source: // Fatal error: Class 'Pimple' not found in ..path.. in the docs i'm missing the actual usage. Shoudl i do: use <classname> or straight ahead "new <classname>(<params>)". What if it's a static class, etc.. I agree, i wasn't clear about that. Despite i thought this kind of usage is trivial. Commented Apr 29, 2012 at 9:36
  • 1
    The use statement need to have the classname appended, I doubth that use \Pimple is correct, maybe use \Pimple\Pimple ? Commented Apr 29, 2012 at 9:39
  • ilanco: Fatal error: Class 'Pimple\Pimple' not found in ...it makes no sense to me to use Pimple\Pimple. Also just to note: Pimple is a DI Container(github.com/fabpot/Pimple), in pimple.php , its a regular "class Pimple implements ArrayAccess" , no namespacing or anything. Commented Apr 29, 2012 at 9:44

2 Answers 2

11

By registering your namespace as follows:

$loader->registerNamespace('App\Location\Location', 'Location/Location');

autoloader will look for the App\Location\Location class in the Location/Location/App/Location/Location.php file. Note that file/directory names are case sensitive.

First parameter of registerNamespace() is either a namespace or part of the namespace. Second parameter is a path to a PSR-0 compliant library. That means that directory structure inside that path should follow PSR-0 standard. This path is not used when calculating path for given namespace.

If you want to keep your current directory structure following code should work for you:

$loader->registerNamespace('App', __DIR__);

I'd rather put your source code in one common directory, for example src:

src/
  App/
    Location/
        Location.php

And then register namespaces as follows:

$loader->registerNamespace('App', 'src');

By doing that you're simply telling an autoloader that it should look for App namespaced classes in the src folder. Note that it will work for every class in the App namespace (following PSR-0).

Some time ago I wrote a blog post about the Symfony autoloader. You might find it helpful: Autoloading classes in an any PHP project with Symfony2 ClassLoader component

Since you plan to use Pimple and some of the Symfony components take a look at Silex microframework. Might be it's something you need to implement.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the clear and constructive answer. Did just that. You've helped me understand what i did wrong, fix it and pointed me to further tools.
and BTW: you can load Pimple with Symfony autoloader just fine.
Tnx! How to do it properly ? :)
2

You use:

$loader->registerNamespace('Pimple', BASE_DIR.'/BE/libs/Pimple/1.0.0/lib/Pimple');

To register the Pimple namespace for Pimple is useless, as Pimple is one class in the default namespace (it has no namespace).

The UniversalClassLoader does only work for PSR-0 and PEAR compatible directory layouts. If your layout is not, you should not expect it to work nor to be documented that it works for incompatbile layouts.

Explicit Note: You are using the wrong tool to do the job. All file layouts you have shared over the last hours are incompatible with UniversalClassLoader.

Apart from that if you give the wrong values for it's parameters, the class just won't work.

14 Comments

Either-way for using the auto-loader functionality, i'd prefer to have it all in the same way. It doesn't work for Pimple nor for: use \APP\Location\Location; new \APP\Location\Location(); gives me: Fatal error: Class 'APP\Location\Location'
I guess you do something wrong with the namespace understanding here. See github.com/symfony/ClassLoader/blob/master/… - Pimple is not PSR-0 nor PEAR compatible. Technically the UniversalClassLoader is the wrong class loader for that library.
I've went over the source a bit, but it didn't help me :/ I know pimple isn't PSR-0 compatible, as it isn't name spaced.. (it should be global), it's not an anti-pattern. Either way, i did testing with the Location class, added a require to the path, worked. It's only: namespace App\Location; class Location{ // implementation} Simplest of classes...
If you know it isn't PSR-0 compatible why are you using the UniversalClassloader for Pimple, that makes no sense.
Short answer: No. Reason: Your direcotry layout with those class and file-names is not PSR-0 compatbible. The loader class you use Unified Class Loader is for PSR-0 compatible or PEAR compatible layouts.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.