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 鼅黏黎黍黉齨鹦鹥鯟鯞龈鸌齬龶齝齚龓鹡齷齍鸌齬龏龎鼕龈鹡齷齘

本书共71小节:

评论 (写第一个评论)