Autoading: it's like plumbing. You forget it's there, but when it's gone, well, let's just say you have to go outside a bit more often.
Autoloading is the magic that lets us use classes without needing to
include the file that holds them first. We used to have
statements everywhere, and well, it was terrible.
But an autoloader has a tricky job: given any class name, it needs to know the exact location of the file that holds that class. In many modern projects, including ours, Composer handles this, and there are two pieces to understanding how it figures out what file a class lives in.
When we create an Event object, Composer's autoloader knows that this class
src/Yoda/EventBundle/Entity/Event.php. How? It just takes
the full class name, flips the slashes, and adds
.php to the end of it:
As long as the namespace matches the directory and the class name matches
the filename plus
.php, autoloading just works. Let's mess this up - let's
Entity directory to
use Yoda\EventBundle\Entity\Event; // the src/Yoda/EventBundle/Entity/Event.php file is "included" // .. so the file better exist and "house" the Event class! new Event();
If we run
play.php now, it fails big:
The autoloader is looking for an
Entity directory. Rename the directory
Entity to fix things.
Right now, it almost looks like the autoloader assumes that everything must
live in the
src/ directory. So how are vendor classes - like Symfony - loaded?
That's the second part. When we fetch a library with Composer, it configures its autoloader to look for the new classes in the directory it just downloaded.
Open up the
vendor/composer/autoload_namespaces.php file. This is generated
by Composer and it has a map of namespaces to the directories where those
classes can be found:
// vendor/composer/autoload_namespaces.php // ... return array( 'Symfony\\' => array($vendorDir . '/symfony/symfony/src'), // ... 'Doctrine\\ORM' => $vendorDir . '/doctrine/orm/lib/', 'Doctrine\\DBAL' => $vendorDir . '/doctrine/dbal/lib/', 'Doctrine\\Common\\DataFixtures' => $vendorDir . '/doctrine/data-fixtures/lib/', // ... );
So when we reference a
Symfony class, it does the slash-flipping trick,
and then looks for the file starting in
Now you know all the secrets about the autoloader. And when you see a class
not found error, it's your fault. Sorry! The most common mistake is easily
use statement. If it's not that, check for a typo in your class