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 鼭黵黱黭黬齾麂麀鯦鯤龐鸜龀龷齷齶龝鹼龇齨鸜龀龚龗鼼龐鹼龇齳

本书共63小节:

评论 (写第一个评论)