Added an exception when passing an invalid object to ApcClassLoader
merged branch stof/autoloader_refactoring (PR #3756)

Commits
-------

f1f1494 Added an exception when passing an invalid object to ApcClassLoader
f5cb167 [ClassLoader] Added a DebugClassLoader using composition
0e54a22 Updated the changelog
eae772e [ClassLoader] Added an ApcClassLoader
4d1333f Changed the test autoloading to use the new autoloader
09850bd [ClassLoader] Added a simplified PSR-0 ClassLoader

Discussion
----------

Autoloader refactoring

Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: [![Build Status](https://secure.travis-ci.org/stof/symfony.png?branch=autoloader_refactoring)](http://travis-ci.org/stof/symfony)

As discussed in #3623, I added a new ClassLoader instead of modifying the UniversalClassLoader, to be able to use the method names without BC concerns. The new class works the same than the composer autoloader regarding the handling of fallbacks, to be able to reuse namespace maps generated by composer.

```php
<?php

// autoload.php
require_once __DIR__.'/vendor/symfony/class-loader/Symfony/Component/ClassLoader/ClassLoader.php';

$loader = new Symfony\Component\ClassLoader\ClassLoader();

$map = require __DIR__.'/vendor/.composer/autoload_namespaces.php';
$loader->addPrefixes($map);

$loader->register();
```

Differences with the composer class loader:

- Composer's ``add`` method is named ``addPrefix`` in the Symfony ClassLoader
- the methods related to the class map are removed as Symfony has a separate laoder for class maps
- the ``addPrefixes`` method is added, accepting a namespace map.

I also added a new ApcClassLoader which uses composition instead of inheriting from a class loader, which makes it far more easier to reuse (we could wrap a Composer autoloader with it for instance).

```php
<?php

$composerLoader = require __DIR__.'/vendor/.composer/autoload.php';

// no need to require the file manually as Composer already registered its autoloader
$cachedLoader = new Symfony\Component\ClassLoader\ApcClassLoader('autoload.my_app', $composerLoader);

$cachedLoader->register();
// unregister the Composer autoloader as we wrapped it in the ApcClassLoader
$composerLoader->unregister();
```

TODO:

- refactor the Debug class loader to use composition too to be able to support different class loaders

---------------------------------------------------------------------------

by fabpot at 2012-04-02T16:31:28Z

Can you update the CHANGELOG and the UPGRADE file accordingly?

---------------------------------------------------------------------------

by stof at 2012-04-02T16:47:43Z

I added a note in the CHANGELOG. There is nothing to add in the UPGRADE file as the change is fully BC (I did not change the UniversalClassLoader at all so it can still be used).

I'm working on the Debug loader right now so please wait a bit before merging

---------------------------------------------------------------------------

by stof at 2012-04-02T17:12:11Z

Here is a new DebugClassLoader using composition too. this way, it is able to support the UniversalClassLoader, the ApcUniversalClassLoader (without dropping the use of APC as done previously), the new ClassLoader, the new ApcClassLoader and even the composer autoloader.
I'm not sure about the use of ``method_exists`` as it could break if an autoloader implements a protected ``findFile`` method (crappy PHP :cry:) but hardcoding the supported classes would be a pain and requiring an interface would make the autoloaders more difficult to use (as the interface would need to be required first) and would drop the support of the composer autoloader.