symfony入门学习资料之十六:Symfony框架启动过程介绍

69 篇文章 0 订阅
5 篇文章 0 订阅

symfony入门学习资料之十六:Symfony框架启动过程介绍

    Symfony框架的核心本质是把Request转换成Response的一个过程。从入口文件(web_dev.php)的源码可以看个大概,此文件从总体上描述了Symfony框架的工作的流程:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<?php

     /*

     * web/app_dev.php

     */

    $loader require_once __DIR__.'/../app/bootstrap.php.cache';

    Debug::enable();

 

    require_once __DIR__.'/../app/AppKernel.php';

        //初始化AppKernel

    $kernel new AppKernel('dev', true);

        //Kernel启动后,载入缓存

    $kernel->loadClassCache();

        //利用一些信息来构造Request对象(如$_GET $_POST等等)

    $request = Request::createFromGlobals();

        //通过symfony内核将Request对象转化为Response对象

    $response $kernel->handle($request);

        //输出Response对象

    $response->send();

         //执行一些邮件发送等耗时操作

    $kernel->terminate($request$response);

?>

从上面的代码来看,大致可以看出的程序的基本思想就是客户端发起请求,Symfony内核通过执行响应的请求,返回响应的Response结果对象,具体symfony是如何执行响应的请求的。通过下面的图可以了解个大概.

也可以通过官方文档得到下面的具体说明:

     客户传入的请求由路由负责解释,并传递给返回响应对象的控制器函数。

     站点的每个“页面”都在一个路由配置文件中定义,该文件将每个url映射到不同的PHP函数。每个PHP函数(称为控制器)的任务使用来自于请求的相关信息,包括Symfony提供的其他工具用来创建和返回响应对象。更进一步的说,控制器是代码所解释请求和创建响应的根源。

 

     在大致了解了路由和控制器的工作流程基础上,再从代码上来看是如何获得Request对象的,在createFromGlobals方法内主要调用createRequestFromFactory方法。
这些参数都是通过http请求后,使用超全局变量self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server);然后再通过构造函数实例化一个Request对象返回。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?php

private static function createRequestFromFactory(array $query array(), 

                               array $request array(), 

                               array $attributes array(), 

                               array $cookies array(), 

                               array $files array(), 

                               array $server array(), 

                              $content = null)

{

    if (self::$requestFactory) {

        $request = call_user_func(self::$requestFactory$query$request$attributes$cookies$files$server$content);

 

        if (!$request instanceof self) {

            throw new \LogicException('The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.');

        }

 

        return $request;

    }

 

    return new static($query$request$attributes$cookies$files$server$content);

}

?>

      createRequestFromFactory 顾名思义是通过工厂来创建request对象在Request的类中有$requestFactory属性,若通过自己实例化一个Request对象类,再通过setFactory()函数设置下工厂,即可以通过自定义,否则即static进行实例化。此时返回一个Request对象。

关于上面的 new static(),与new self()的区别。

    self引用了发生新操作的类的方法。静态绑定是指在层次结构中调用方法的任何类。在下面代码的示例中,B从A继承了两个方法。self被绑定到A,因为它是在A的第一个方法的实现中定义的,而static被绑定到被调用的类(参看get_called_class()里的说明)。
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?php

class A {        //类A

  public static function get_self() {

    return new self();

  }

  

  public static function get_static() {

    return new static();

  }

}

  

class extends A {}   //派生类B

  

echo get_class(B::get_self()); // A

echo get_class(B::get_static()); // B

echo get_class(A::get_static()); // A

?>

在上面的例子代码中很容易得出:在Controller中可以通过Request对象获取相的参数,处理数据后,返回一个Response对象。下面的代码可以知道是怎样返回一个Response对象的。

详见$kernel->handle($request);

1

2

3

4

5

6

7

8  

9

10

11

12

13

14

15

16

<?php

/**

 * {@inheritdoc}

 */

public function handle(Request $request$type = HttpKernelInterface::MASTER_REQUEST, $catch = true)

{

            //symfony内核只启动一次

    if (false === $this->booted) {

            //注册所有的Bundles

            //初始化container, 加载、缓存配置数据和路由数据等,

        $this->boot();

    }

            //内核处理请求

    return $this->getHttpKernel()->handle($request$type$catch);

}

?>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<?php

/**

 * Boots the current kernel.

 */

public function boot()

{

    if (true === $this->booted) {

        return;

    }

 

    if ($this->loadClassCache) {

        $this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]);

    }

 

            // 里面调用kernel->registerBundles()

    $this->initializeBundles();

 

           // 初始化container,包括载入配置信息、编译信息等

           //Symfony2的核心组件的加载

    $this->initializeContainer();

           //将各个bundle注入container,以便能使用其内容

           //并启动bundle

    foreach ($this->getBundles() as $bundle) {

        $bundle->setContainer($this->container);

        $bundle->boot();

    }

 

    $this->booted = true;

}

?>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

<?php

//内核处理请求,下面是主要的信息,就是通过请求,执行相应的controller,渲染view

private function handleRaw(Request $request$type = self::MASTER_REQUEST)

    {

        $this->requestStack->push($request);

 

                   // 请求对象

        $event new GetResponseEvent($this$request$type);

        $this->dispatcher->dispatch(KernelEvents::REQUEST, $event);

 

        if ($event->hasResponse()) {

            return $this->filterResponse($event->getResponse(), $request$type);

        }

 

                  // 载入响应的controller

        if (false === $controller $this->resolver->getController($request)) {

            throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.'$request->getPathInfo()));

        }

 

        $event new FilterControllerEvent($this$controller$request$type);

        $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);

        $controller $event->getController();

 

                 // controller的参数

        $arguments $this->resolver->getArguments($request$controller);

 

                // 调用controller

        $response = call_user_func_array($controller$arguments);

 

                // view

        if (!$response instanceof Response) {

            $event new GetResponseForControllerResultEvent($this$request$type$response);

            $this->dispatcher->dispatch(KernelEvents::VIEW, $event);

 

            if ($event->hasResponse()) {

                $response $event->getResponse();

            }

 

            if (!$response instanceof Response) {

                $msg = sprintf('The controller must return a response (%s given).'$this->varToString($response));

 

                 

                if (null === $response) {

                    $msg .= ' Did you forget to add a return statement somewhere in your controller?';

                }

                throw new \LogicException($msg);

            }

        }

 

        return $this->filterResponse($response$request$type);

    }

?>

此时就返回一个Response对象,发送至客户端,在页面上就可以看到其返回的内容了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jyl_sh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值