class Pimple implements ArrayAccess { function share($callable); function protect($callable); function raw($id); function extend($id, $callable); function keys(); }
class Pimple implements ArrayAccess { function share($callable); function protect($callable); function raw($id); function extend($id, $callable); function keys(); }
// user.repository is redefined/extended $app['user.repository'] = $app->share($app->extend( 'user.repository', function ($repo) { return new CachingRepository($repo); } )); // but user.service already has the uncached version $app['user.service']-> ....
namespace Acme\Common; trait PimpleAutoWiring { public function bindType($type, $service) { $this->boundTypes[$type] = $service; } public function resolve($type, array $fixedArgs = array()) { $boundTypes = &$this->boundTypes; return function ($app) use ($type, &$boundTypes, $fixedArgs) { $rfc = new \ReflectionClass($type); $ctor = $rfc->getConstructor(); $args = array(); foreach ($ctor->getParameters() as $param) { $classHint = $param->getClass()->getName(); if ($classHint) { if (isset($boundTypes[$classHint])) { $args[] = $app[$boundTypes[$classHint]]; } else if (isset($app[$classHint])) { $args[] = $app[$classHint]; } else if (isset($app[$param->getName()])) { $args[] = $app[$param->getName()]; } else { throw new \RuntimeException("Could not resolve service for $classHint"); } } else { if (isset($fixedArgs[$param->getName()])) { $args[] = $fixedArgs[$param->getName]; } else { throw new \RuntimeException("Could not resolve parameter for {$param->getName} for $type"); } } } return $rfc->newInstanceArgs($args); }; } } ~50 slocs Could do with some caching
function get($pattern, $to = null); function post($pattern, $to = null); function put($pattern, $to = null); function delete($pattern, $to = null); function match($pattern, $to = null);
function get($pattern, $to = null); function post($pattern, $to = null); function put($pattern, $to = null); function delete($pattern, $to = null); function match($pattern, $to = null);
namespace Acme\User; use Silex\Application; use Silex\ControllerProviderInterface; use Silex\ServiceProviderInterface; class Provider implements ControllerProviderInterface, ServiceProviderInterface { public function register(Application $app) {} public function boot(Application $app) {} public function connect(Application $app) {} }
// Acme\User\Module public static function register(Application $app) { $app->register(new ServiceProvider()); $app->mount('/', new ControllerProvider()); $app->mount('/', new AdminControllerProvider()); } // app/app.php Acme\User\Module::register($app);
// abstract class BaseController public function setApplication(Application $app) { $this->app = $app; } public function get($key) { return $this->app[$key]; }
Name Method Pattern Controller Method users.index GET /users indexAction users.new GET /users/new newAction users.create POST /users newAction users.show GET /users/{id} showAction($id) users.edit GET /users/{id}/edit editAction($id) users.update PUT /users/{id} editAction($id) users.delete DELETE /users/{id} deleteAction($id)
Laravel 4.1 features a totally re-written routing layer. The API is the same; however, registering routes is a full 100% faster compared to 4.0. The entire engine has been greatly simplified, and the dependency on Symfony Routing has been removed.
Summary •Treat a Silex app like any other app •Pimple requires care when you have a lot of services •Namespace and name everything •Lazyness for as much as possible •Silex’ API is narrow, scope widens when you dig around inside •Silex has to do a lot of work for every request, grows linearly with your app