Symfony is a set of reusable standalone PHP components that can be used to solve many web dev problems. We will pick some of the important components (bricks) & will create our own framework on top of those bricks.
7. Utilising “Front Controller” design pattern
• src/ : source code for our app (not publiciy accessible)
vendor/ : any third-party Libraries
web/ : use to house anything that needs to be accessible from the web server,
including assets & out front controller
8. Lets see code snippet after implementing FrontController
(pt2)
9. Mapping URLs with Routing Component
Routing component documentation
Basic parts of routing system
• RouteCollection – contains the route definitions (instances of class Route)
• RequestContext - contains information about Request
• UrlMatcher – performs the mapping of the Request to a single Route
$ composer require symfony/routing
10. New version of our framework using Routing Component
// simplex/web/index.php
require_once __DIR__.'/vendor/autoload.php';
$request = Request::createFromGlobals();
$routes = include __DIR__.'/../src/routes.php';
$context = new RoutingRequestContext();
$context->fromRequest($request);
$matcher = new RoutingMatcherUrlMatcher($routes, $context);
try {
extract($matcher->match($request->getPathInfo()), EXTR_SKIP);
ob_start();
include sprintf(__DIR__.'/../src/pages/%s.php', $_route);
$response = new Response(ob_get_clean());
} catch (RoutingExceptionResourceNotFoundException $e) {
$response = new Response('Not Found', 404);
} catch (Exception $e) {
$response = new Response('An error occurred', 500);
}
$response->send();
// example.com/src/routes.php
use SymfonyComponentRouting;
$routes = new RoutingRouteCollection();
$routes->add('hello', new RoutingRoute('/hello
array('name' => 'World')));
$routes->add('bye', new RoutingRoute('/bye'))
return $routes;
11. Lets see code snippet after implementing
RoutingComponent (pt3)
12. Introducing Controllers in Routing Component
// simplex/src/routes.php
$routes->add('hello', new RoutingRoute('/hello/{name}', array(
'name' => 'World',
'_controller' => function ($request) {
// $foo will be available in the template
$request->attributes->set('foo', 'bar');
$response = render_template($request);
// change some header
$response->headers->set('Content-Type', 'text/plain');
return $response;
}
)));
// simplex/web/index.php
try {
$request->attributes->add($matcher->match($request->getPathInfo()));
} catch (RoutingExceptionResourceNotFoundException $e) {
$response = new Response('Not Found', 404);
} catch (Exception $e) {
$response = new Response('An error occurred', 500);
}
$response = call_user_func($request->attributes->get('_controller'), request);
'_controller' => function ($request) {
// $foo will be available in the template
$request->attributes->set('foo', 'bar');
$response = render_template($request);
// change some header
$response->headers->set('Content-Type','text/plain');
return $response;
}
13. Lets see code snippet after implementing Controller in
RoutingComponent (pt4)
15. $ composer require symfony/http-kernel
A non-desirable side-effect , noticed it ??
16. HttpKernel Component : The Controller Resolver
Using Controller Resolver
public function indexAction(Request $request)
// won't work
public function indexAction($request)
// will inject request and year attribute from request
public function indexAction(Request $request, $year)
18. Lets see code snippet after implementing
ControllerResolver (pt5)
This completes part 1 of series
Projects using Symfony2 components
19. Downsides in our framework code
• We need to copy front.php each time we create a new website.
It would be nice if we could wrap this code into a proper class
24. Separation of concerns (MVC) continued..
Our application has now Four Different layers :
1. web/front.php: The front controller, initializes our application
2. src/Simplex: The reusable framework class
3. src/Calendar: Application specific code (controllers & models)
4. src/routes.php: application specific route configurations