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 黾黄黁黀麾齙鹝鹚鯋鯇齹鸁齜龸齒齎龉鹙齬鼼鸁齜龅龂鼏齹鹙齬齊

本书共88小节:

评论 (写第一个评论)