17. 控制器执行及其解析器controller_resolver

drupal HttpKernel 龓龒龐龏龎龍龉龅龄龃龅龂齿齽齼齸齷龦龍龉龅齳齰齮龄龃齫龍龉龅齧齼龦齣齢齡齞齜齘齖齒龶齐齎齊齈龎齅齁齳鼾鼼鼹鼶齢鼴龦鼰鼯龄龃齳鼭鼬齎鼨鼤鼣鼡齡

齁龦鼟鼛 ID 鼑鼎 controller_resolver 齳黿黻齰黹黷齎齣齢鼎

psr7.http_message_factory 鼎龎黨黤黠 psr7 黟黝龦黛黚黖黒齡黏黌黨黊齎黛黆鼎 http://www.php-fig.org/psr/psr-7/

class_resolver 鼎麮鼡龅麫麩齿鼟鼛齡

工作原理

齁齧齼麥麤 ControllerResolverInterface 黿麛齳麫麩麚黷齎齈麗麖麒鼎

public function getController(Request $request); // 鹿鼰鼬齎鼰鼯鹻鼑龍龉龅

public function getArguments(Request $request, $controller); // 黚齫龍龉龅龦齣齢齳鹵齰鹱鹰齢鼴龦齈鹯鹿鼰

黊齎鼭 Symfony 龦黿麛麖麒齳齜齖 drupal 鹫鹩鼬齎齈麗鼎

public function getControllerFromDefinition($controller); // 齰鹤鹣龐黖龍龉龅龦麖麒龂鹠齿龍龉龅齳鹟鹞鹿鼰鼰鼯

鹜齰 drupal 龦龍龉龅龄龃龅鼬鹚齼麥麤黿麛龦齰鹘鹕齎齈麗齡

鹑黆鼬黆齁鹎鹌龄龃齫龍龉龅鼎

黊鹋鹉鹇鹅黨鹤鹣鹃鸿龐龶黛黚黖黒鸾鸼鸻鹘鸸鸷龦 _controller 齣齢齳鸵鸴鼼黹鼎

$request->attributes->get('_controller'))

龄龃鸬鼭鸫黨 _controller 龦鼣鼡齡

鹜麚鸨鹃鹤鹣鸦鸢龦黛黚黖黒鹘鼬麖鸟麚 _controller 鸝鸙齳齁龂鸖鹤鹣麖麒龦 defaults 鸓鸒

鸐鸍鸋鸉鸆龶麚鸅鹤鹣麖麒龐鸃麚麖麒 _controller 鷿鷽

鸃麚麖麒 _controller 龦鹤鹣鸟龶鹤鹣鷺鷹龅麫麩麖麒齳鼾鼼鸦鸢鷵鷱龦鹤鹣麫麩麖麒鹩 _form 齳鷯鸃麚麖麒 _controller

鷫龶鷺鷹龅 FormRouteEnhancer 龐鸬麖麒鹩

$defaults['_controller'] = 'controller.form:getContentResult';

鷜龐鼎 controller.form 鷵鷛鼟鼛 ID 齳麥鷙齒鼭鷗鷕鷓鷒齳黊齎龎麗鷎黹鷋齳鷉鷆鸿齅鷅黊麫鷂齳鷁齘鼬麖麚 _controller 黊齎鸝鸙鸸鸷龶黛黚鸾鸼鸻龐齡

_controller 龦麖麒鼎齁鸍齰鼭鶿齢鶽鶻鶺鶷鶶 __invoke 齈麗龦黖黒齳齒鸍齰鶳鼭鼬齎鷗齳鷫齁鹋鹉鸻鶯 __invoke 齈麗齡

鷗鶽鹋鹉鼭鶫鶧麖龦鶽鸓鶣鶠鷗鶽齳龍龉龅鸸鸷鶜鸋龏龎鹤鶛鶽齳鶗鶓鸟鶑鹃鷗鹫鶐龅鶍齅龍龉龅齡鶉齐齢鷓鷒鼭龎 : 鶻鶺 :: 鶈鶆龦鸓鶄鶂齳齁鷵鷛鶁齎鷗龦鶁齈麗齳龶黊麫 : 鵿 :: 鸃麚鵽鵼齡黊齎鶈鵸鶄鵷麚齎鵳鵰龦龎麗齳鵯麩鵭鶈鶜鼬麖鼭鷗鶽齒鸍齰鼭鼡龅龦鼟鼛鶽齳鹜齰鸍齰齸齷鼡龅龦鼟鼛齈麗齡

黊齎鵳鵰龎麗鼭龶 class_resolver 鼟鼛龐麥麤龦齳鹘鷋鵬鸨鵩鹩齁鹻鼑齣齢鵦鵣鵡龍龉龅龄龃龅齡

鷗麖麒龶 \core\lib\Drupal\Core\DependencyInjection\ClassResolver.php

黊麫齧齼鵖鵓龦鼭龶 : 鶻鶺 :: 齘鵯龦鵭鶈鼼鵏鼭鼬齎鷗齳鹵鵍齁麥麤鹩齰黹黿麛鼎

Drupal\Core\DependencyInjection\ContainerInjectionInterface

Symfony\Component\DependencyInjection\ContainerAwareInterface

鵌鹌齁鸟鵈麥鵆鵃鹵鸖鵀鵖鴽鼟鼛鼡龅齳龶 drupal 龐鴹鴸鶫鵭鼟鼛鴷龶鼡龅龐齳

ControllerBase 麥麤鹩 ContainerInjectionInterface 齳齁鸬鼭齜鷂鸖鵀鵖鴽鼡龅齳鹜齰鸋鴯鴭鵌鸅鴫龎龦鼟鼛

鴪鴩鼑鴨鹌龍龉龅鴥鴢 Drupal\Core\Controller\ControllerBase 鸬鸟麚鼡龅鹩鴡鴞

齰鹘鸬鼭鹠齽龍龉龅龦鹃鸿齳鸨鹃龍龉龅龄龃龅鸦鸢鹿鼰鹩鼬齎鼰鼯齡

鴝黿鴛龓龒龶齽齅鼰鼯鴚鸟鴘鴔 kernel.controller 鴓鴐齳鶗鶓鴍鴋鴯鴭鹩黷齎鴊鴈龅鼎

鼟鼛 id path_subscriber 齈麗鼎 onKernelController 鹻龎鼭鴅鵼鶽鴄鸢龅鸸鸷鴂鳿鳼

鼟鼛 id:early_rendering_controller_wrapper_subscriber 齈麗鼎 onController 鹻龎鼼黹鼎

黊齎鴊鴈龅鵳鵼鼨齼齳鷫齒鴅鳸鳷鳶鵳鵼鵼鳴齳龶龍龉龅齸齷龦鷂鳰齼鼹鼶鳭麩鳩鳦鳣鹿鼰鼹鼶齢鼴齡

鷫鸍鸋齒鸟龶龍龉龅龐鳡黿鼯龎 drupal_render() 龂鼹鼶齳黊鹞鹃鳠龦鼹鼶鳟鼑鼎 "early rendering"齡

黊鹞鳛鸟鴅鶗鶓鴊鳗鶜齅鼹鼶鹘黹鷋齳鳔鳒鼬鸅鳏齢鳋齳鳇鳃齅鴂鳿鳁鳁齳鹜齰 drupal8 龏龎黊齎鴊鴈龅龂龄鲽黊齎鲼鲻

黏鹃鳠鼹鼶龶 drupa9 龐鸟鵈鲷齞齳鲵鲲龏龎麲齳鵌鹌齁鼭鹎鹌龄鲽龦鷿鷽

鷜麥鹜麚龦龍龉龅鴷鵈黊齎鴊鴈龅鸻鲮龶鹩鼬齎鲪鸻麫麩齳龶鲪鸻龐龄鲽齳 Symfony HttpKernel 齽齅龦龍龉龅鶫鼭鸨鹃鸻鲮龦齡

鲨鲦龦齣齢龄龃鲥鹻齒龶黊麫鲤齷齳龶 \Symfony\Component\HttpKernel\HttpKernel::handleRaw() 龐鲤齷龦齣齢龄龃鲠鸾鲜鲙鲖鲔齳鷫齁鲐鲌鼭鲉鹕齈鲅齳鸵鸴鶜黻 drupal 龍龉齳鴩鴩鲜鲙鲄鲂鲖鲔鹩齳鲀鶺鸍齰鱼鱼龶 handleRaw() 龐齣齢龄龃鴚麩鼨鸷齣齢鼑鶣齢鼴齳鶗鶓鱺齷鱹鹞鼭鸃麚鱸鱷鲼鲻龦齳黊麫黠鱳 drupal8 龦龍龉龅龄龃龅齼鸸鸷鴂鳿鱯龉齳鱭鱪黊鱩鲜鲙齳齣齢龄龃龦鱧鱥鱢鹻鼭鱟鱝鲖鲔龦齡

鹣黨黊齎鴊鴈龅龦鵳鵰鹻龎齳鷉鱜鱛龶鵖鱗 kernel.controller 鴓鴐鴊鴈龅鷂鼬麖齼鵖鵓鱔鹑鱑齳齜鴊鴈龅鱔鹑鱑鼑鴍鴋龦 0

下面来看一看控制器解析器是怎么获取参数的,一句话总结:使用php的反射机制。

鱍齐 drupal 龦鱊鱉鶺鳦鳣鴷鱆鸉鹃龍龉龅龦齣齢鲼鲻鴡齳龓龒鸵鸴鼼鱂鰾鼣鼡鵽鼎

齣齢鼎 $parameters 鼭鼬齎 ReflectionParameter 黖黒鼴鰸龦齢鼴齳鷎鼎 http://php.net/manual/zh/class.reflectionparameter.php

齁龂鸖齰黹齈麗龐鼎

   public function getArguments(Request $request, $controller)
    {
        if (is_array($controller)) {
            $r = new \ReflectionMethod($controller[0], $controller[1]);
        } elseif (is_object($controller) && !$controller instanceof \Closure) {
            $r = new \ReflectionObject($controller);
            $r = $r->getMethod('__invoke');
        } else {
            $r = new \ReflectionFunction($controller);
        }

        return $this->doGetArguments($request, $controller, $r->getParameters());
    }

麮齰鹘龄龃鹃鸿龐鸍齰鰟鰛龍龉龅齣齢鰙龎龦鰖鰒鰐鰍鶽鰌鰊鰐鷗鰇鰆鷛鼎

鹑麮 $request->attributes 鶍鹟鶽齣齢齳黊齒鼭鼑鴨鹌鹤鹣麖麒龐鰅齖齣齢鸋鹻鼑龍龉龅齣齢龦鰂鰁齳鹤鹣麖麒龦鯽鯹鶄鶽齼鵿龍龉龅齣齢鶽鼬鯸齡

鯴麮 $request->attributes 龐龦 _raw_variables 鶍鹟鶽齣齢齳齁鼭鯱鸨鹃鯮鯪龦鰂鯧鸝鸙齡

鯴黆齣齢鼭鶜鼭麚鷗鰇鰆鷛鼑黛黚黖黒齳鼼鵏鼭鰊鯥黛黚鹻鼑齣齢齡

鯴黆鼭鶜鼭 psr7 黟黝龦黛黚鷗鰇齳齁麥麤 ServerRequestInterface 黿麛齳鼼鵏鼭鰊鯮鵃黛黚鹵鵦鵣齡

鯴黆鷗鰇鰆鷛鼭鶜鼭鹤鹣鯣鯡龅黏 RouteMatchInterface 鶻鷜鯟鷗麲齳鼼鵏鼭鰊鵦鵣鹤鹣鯣鯡龅齡

鯛鴚鵦鵣齣齢龦鴍鴋鯚齳鼼鵏鶜鸋鶍齅齣齢鯥鯗鯕齡

protected function doGetArguments(Request $request, $controller, array $parameters) {
    $attributes = $request->attributes->all();
    $raw_parameters = $request->attributes->has('_raw_variables') ? $request->attributes->get('_raw_variables') : [];
    $arguments = array();
    foreach ($parameters as $param) {
      if (array_key_exists($param->name, $attributes)) {
        $arguments[] = $attributes[$param->name];
      }
      elseif (array_key_exists($param->name, $raw_parameters)) {
        $arguments[] = $attributes[$param->name]; //在8.2.3及之前的版本中,这里是一个bug,此处应该是$raw_parameters[$param->name],笔者已经提交了bug报告
      }
      elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
        $arguments[] = $request;
      }
      elseif ($param->getClass() && $param->getClass()->name === ServerRequestInterface::class) {
        $arguments[] = $this->httpMessageFactory->createRequest($request);
      }
      elseif ($param->getClass() && ($param->getClass()->name == RouteMatchInterface::class || is_subclass_of($param->getClass()->name, RouteMatchInterface::class))) {
        $arguments[] = RouteMatch::createFromRequest($request);
      }
      elseif ($param->isDefaultValueAvailable()) {
        $arguments[] = $param->getDefaultValue();
      }
      else {
        if (is_array($controller)) {
          $repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
        }
        elseif (is_object($controller)) {
          $repr = get_class($controller);
        }
        else {
          $repr = $controller;
        }

        throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
      }
    }
    return $arguments;
  }

齰鹘鸬鼭龍龉龅龄龃龅龦鶫鵭鼣鼡鹩齳齰黹鼭鼬鸅鯓鯒鼎

1 鼎龶 drupal8 龐鹜麚龍龉龅鼭鯎龶鲪鸻麫麩齸齷龦齳黊鹞鳛鼭鱭鱪鹃鳠鼹鼶鯊龂龦鲼鲻齳齜鵳鸼龶 D9 龐鲷齞鯈

2 鼎龍龉龅鯛鱆麖麒鴍鴋鯚齳鯂鰊鷉鶍鶜齅鯚鷂鸟鯗鯕鯈

3 鼎龍龉龅鯛鱆鴥鴢 Drupal\Core\Controller\ControllerBase 齳黊鹞鼾鮼齈鮸龏龎鯈

4 鼎黛黚黖黒齮鹤鹣鯣鯡龅鸍齰龶齣齢龐鹠齽齒鸍齰龏龎鼡龅鹠齽齡

本书共78小节:

评论 (写第一个评论)