AppBundle, Routing and Annotations
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeNow, we need to build a route and create a page. But I want to do this with as few files as possible. Remember, we're going for micro here!
In Symfony, your PHP code lives in a bundle. But actually, you don't need a bundle at all: you could code entirely without one. And this could give us one less file.
In practice, not having a bundle complicates a few things. So, we will create one here, but if you're curious about the approach, ask me in the comments, or read our AppBundle blog post that talks about this.
Creating AppBundle
Create a new directory called just AppBundle
- not src/AppBundle
- I want to eliminate some directories! Put a new PHP class in there also called AppBundle
in an AppBundle
namespace. Make this class extend Bundle
:
// ... lines 1 - 2 | |
namespace AppBundle; | |
use Symfony\Component\HttpKernel\Bundle\Bundle; | |
class AppBundle extends Bundle | |
{ | |
} |
Activate this in AppKernel
with new AppBundle/AppBundle()
:
// ... lines 1 - 5 | |
class AppKernel extends Kernel | |
{ | |
public function registerBundles() | |
{ | |
$bundles = array( | |
// ... lines 11 - 13 | |
new \AppBundle\AppBundle() | |
); | |
// ... lines 16 - 17 | |
} | |
// ... lines 19 - 23 | |
} |
Routing
Cool - that's the last time you'll need to do that. Now let's create a page. Open routing.yml
. To minimize the number of files I need to touch I'll use annotation routing. If you prefer YAML, you can start adding your routes here, point them to controller classes and be on your way.
For us, add an import: resource: @AppBundle/Controller
with type: annotation
:
app_annotations: | |
resource: "@AppBundle/Controller" | |
type: annotation |
In AppBundle
, create the Controller
directory and a new class in there called MighyMouseController
in honor of another small, but powerful thing.
// ... lines 1 - 2 | |
namespace AppBundle\Controller; | |
// ... lines 4 - 7 | |
class MightyMouseController | |
{ | |
// ... lines 10 - 16 | |
} |
Add public function rescueAction()
and return a new Response()
: "Here I come to save the day!":
// ... lines 1 - 4 | |
use Symfony\Component\HttpFoundation\Response; | |
// ... lines 6 - 7 | |
class MightyMouseController | |
{ | |
// ... lines 10 - 12 | |
public function rescueAction() | |
{ | |
return new Response('Here I come to save the day!'); | |
} | |
} |
For routing, it's like normal: add the use
statement for Route
. Then above the method, finish things with @Route("/")
:
// ... lines 1 - 5 | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | |
// ... line 7 | |
class MightyMouseController | |
{ | |
/** | |
* @Route("/") | |
*/ | |
public function rescueAction() | |
{ | |
// ... line 15 | |
} | |
} |
Autoloading!
Let's see if things work. Error! Where are you when we need you Mighty Mouse?
Attempted to load class "AppBundle" from namespace AppBundle.
The autoloader doesn't know that we have classes living inside the AppBundle
directory. In a traditional Symfony project, there's a pre-made autoload
section in composer.json
that takes care of this for us. We on the other hand need to do this manually.
Add an autoload
section, with a psr-4
section below it. Inside, we need just one entry AppBundle\\
mapped to AppBundle/
:
{ | |
// ... lines 2 - 12 | |
"autoload": { | |
"psr-4": { | |
"AppBundle\\": "AppBundle/" | |
} | |
} | |
} |
This says that if a class's namespace starts with AppBundle
, look for it inside the AppBundle
directory. After that, it follows the same namespace rules as always. You can even rename AppBundle
to something else like src
- this is the only line you'd need to change.
To get the change to take effect, run composer dump-autoload
:
composer dump-autoload
You don't normally need to run this - it happens after a composer install or update.
Autoloading Annotations
Try it again. Excellent - the next error!
The annotation "@Sensio\Bundle\FrameworkExtraBundle\Configuration\Route"
... does not exist.
It doesn't see the Route
annotation class - it's almost as if we forgot the use
statement. If you use annotations in a project, you need one extra autoload line.
In the config/
directory, create an autoload.php
file. Go back to the Standard Edition code so we can cheat off of it. Find app/autoload.php
and copy its contents. Paste that here:
// ... lines 1 - 8 |
I'll delete some comments to make things really small. This includes the normal autoloader, then adds an extra thing for annotations. Now, in index.php
- or anywhere else you need to autoload - require this file instead:
// ... lines 1 - 10 | |
$loader = require_once __DIR__.'/../config/autoload.php'; | |
// ... lines 12 - 24 |
Refresh! Very nice! Let's count the files: 1, 2, 3, 4, 5, 6, 7. We're rocking the Symfony framework with basically less than 10 files.
Many thanks! You save my time and life :) This line many helped me: "composer dump-autoload"