One down-side of our framework right now is that we need to copy and paste the
code in front.php each time we create a new website. 40 lines of code is
not that much, but it would be nice if we could wrap this code into a proper
class. It would bring us better reusability and easier testing to name just
a few benefits.
If you have a closer look at the code, front.php has one input, the
Request, and one output, the Response. Our framework class will follow this
simple principle: the logic is about creating the Response associated with a
Request.
As the Symfony2 components requires PHP 5.3, let's create our very own
namespace for our framework: Simplex.
Move the request handling logic into its own Simplex\Framework class:
<?php
// example.com/src/Simplex/Framework.php
namespace Simplex;
use Symfony\Component [HttpFoundation\Request;] use Symfony\Component [HttpFoundation\Response;] use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component [HttpKernel\Controller\ControllerResolver;]
class Framework
{
protected $matcher;
protected $resolver;
public function __construct(UrlMatcher $matcher, ControllerResolver $resolver)
{
$this->matcher = $matcher;
$this->resolver = $resolver;
}
public function handle(Request $request)
{
try {
$request->attributes->add($this->matcher->match($request->getPathInfo()));
$controller = $this->resolver->getController($request);
$arguments = $this->resolver->getArguments($request, $controller);
return call_user_func_array($controller, $arguments);
} catch (ResourceNotFoundException $e) {
return new Response('Not Found', 404);
} catch (\Exception $e) {
return new Response('An error occurred', 500);
}
}
}
And update example.com/web/front.php accordingly:
<?php
// example.com/web/front.php
// ...
$request = Request::createFromGlobals();
$routes = include __DIR__.'/../src/app.php';
Truncated by Planet PHP, read more at the original (another 8017 bytes)