/** * @return mixed|null * @throws \RuntimeException * @throws \Exception */ public function run() { $this->initialize(); // default error handling if (!isset($this->callbacks['Application.Error'])) { $this->addFeature(new Feature\BasicErrorHandler()); } /** @var $router Router */ $router = $this->serviceLocator->get('Router'); $this->trigger('Application.PreRoute'); try { $routeMatch = $router->route(); $this->serviceLocator->set('RouteMatch', $routeMatch, true); } catch (\Exception $e) { return $this->trigger('Application.Error', array('type' => self::ERROR_EXCEPTION, 'exception' => $e)); } $this->trigger('Application.PostRoute'); if ($routeMatch == null) { /** @var $router Router */ $router = $this->serviceLocator->get('Router'); $routeMatch = $router->getLastRouteMatch(); if (!$routeMatch) { return $this->trigger('Application.Error', array('type' => self::ERROR_UNROUTABLE)); } } elseif (!$routeMatch instanceof Router\RouteMatch) { throw new \InvalidArgumentException('Provided RouteMatch must be of type P\\Router\\RouteMatch'); } $route = $routeMatch->getRoute(); if (!$route instanceof Router\RouteInterface) { throw new \RuntimeException('Matched route must implement MiniP\\ApplicationRoute\\ApplicationRouteInterface'); } $this->trigger('Application.PreDispatch'); try { $routeSource = $router->getSource(); $dispatchParams = $routeMatch->getParameters(); if ($routeSource instanceof Router\HttpSource) { $dispatchParams['HttpUri'] = $routeSource['uri']; $dispatchParams['HttpMethod'] = $routeSource['method']; } $this->applicationState->pushScope('Application.Dispatch', $dispatchParams); try { $callable = get_callable($route->getDispatchable(), $this->applicationState); } catch (\Exception $e) { $this->applicationState->popScope(); return $this->trigger('Application.Error', array('type' => self::ERROR_UNDISPATCHABLE)); } $result = invoke($callable, $this->applicationState, null, false); $this->applicationState->setResult($result); $this->applicationState->popScope(); } catch (\Exception $e) { $this->applicationState->popScope(); return $this->trigger('Application.Error', array('type' => self::ERROR_EXCEPTION, 'exception' => $e)); } $this->trigger('Application.PostDispatch'); }
ini_set('display_errors', '1'); echo '<p style="background-color:#ccc; font-family:arial;">Service Locator</p>'; //~ require 03-dependeny-injection.php //~ class Pizza //~ { //~ public function __construct ( CrustInterface $crust ) //~ { //~ $this-> crust = $crust; //~ } //~ public function addTopping ( ToppingInterface $topping ) //~ { //~ $this-> toppings [] = $topping; //~ } //~ } class ServiceLocator { protected $services = array(); public function set($id, $className) { $this->services[$id] = new $className(); } public function get($id) { return $this->services[$id]; } } $s1 = new ServiceLocator(); $s1->set('wheat-crust', 'CrustWheatFlour'); $s1->set('salami', 'ToppingSalami'); $s1->set('cheese', 'ToppingCheese'); //~ $pizzaSalami new Pizza ($s1->get('wheat-crust'));
} public function set($name, $val) { $this->dependencies[$name] = $val; } } class Router { protected $request; protected $response; public function __construct(ServiceLocator $sl, $path) { $this->request = $sl->get('request'); $this->response = $sl->get('response'); $this->path = $path; // … } } // Create SL $sl = new ServiceLocator(); // Tell DiC how to create dependencies $sl->set('request', function () { return new Request(); }); $sl->set('response', function () { return new Response(); }); // Create a router, injecting the dependencies $router = new Router($sl, '/hello'); echo '<pre>'; var_dump($router);