想了解symfony的启动过程,必须从启动文件(这里就以开发者模式)开始。

<?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是如何执行响应的请求呢?下面通过官方文档看下

Incoming requests are interpreted by the routing and passed to
controller functions that return Response objects.Each “page” of your
site is defined in a routing configuration file that maps different URLs
to different PHP functions. The job of each PHP function, called a
controller, is to use information from the request – along with many
other tools Symfony makes available – to create and return a Response
object. In other words, the controller is where your code goes: it’s
where you interpret the request and create a response.

先大致了解一下其工作流程,下面我们来看如何获得Request对象的,在createFromGlobals方法内主要调用createRequestFromFactory方法。

这些参数都是通过http请求后,使用超全局变量self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES, $server);

再通过构造函数实例化一个Request对象返回。

<?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 refers to the same
class whose method the new operation takes place in.static in PHP 5.3
is late static bindings refers to whatever class in the hierarchy which
you call the method on.In the following example, B inherits both methods
from A. self is bound to A because it’s defined in A’s implementation
of the first method, whereas static is bound to the called class (also
see get_called_class() ).

其实通过一个实例就显而易见

<?php
class A {
public static function get_self() {
return new self();
}

public static function get_static() {
return new static();
}
}

class B extends A {}

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);

<?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);
}
?>
<?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;
}
?>
<?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对象,发送至客户端,我们就可以看到其内容啦。

Symfony启动过程详细学习的更多相关文章

  1. 【ARM-Linux开发】U-Boot启动过程--详细版的完全分析

    ---------------------------------------------------------------------------------------------------- ...

  2. hadoop namenode启动过程详细剖析及瓶颈分析

    NameNode中几个关键的数据结构 FSImage Namenode 会将HDFS的文件和目录元数据存储在一个叫fsimage的二进制文件中,每次保存fsimage之后到下次保存之间的所有hdfs操 ...

  3. Activity 的启动过程深入学习

    手机应用也是一个app,每一个应用的icon都罗列在Launcher上,点击icon触发onItemClick事件. 我们要启动「淘宝」这个App,首先我们要在清单文件定义默认启动的Activity信 ...

  4. 2440nandflash启动过程再学习

    2011-02-13 12:27:05 2440nandflash启动,先是nandflash的前4K自动复制到CPU的0x0地址开始的4K区域. 然后CPU开始运行这4K(刚才copy过来的代码), ...

  5. (一)U-Boot启动过程--详细版的完全分析

    博客地址:http://blog.csdn.net/hare_lee/article/details/6916325

  6. Linux内核分析 实验三:跟踪分析Linux内核的启动过程

    贺邦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一. 实验过程 ...

  7. Nginx学习笔记(六) 源码分析&启动过程

    Nginx的启动过程 主要介绍Nginx的启动过程,可以在/core/nginx.c中找到Nginx的主函数main(),那么就从这里开始分析Nginx的启动过程. 涉及到的基本函数 源码: /* * ...

  8. Android应用程序的Activity启动过程简要介绍和学习计划

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6685853 在Android系统中,Activ ...

  9. openstack学习笔记一 虚拟机启动过程代码跟踪

    openstack学习笔记一 虚拟机启动过程代码跟踪 本文主要通过对虚拟机创建过程的代码跟踪.观察虚拟机启动任务状态的变化,来透彻理解openstack各组件之间的作用过程. 当从horizon界面发 ...

随机推荐

  1. MySQL在创建相同表结构时as和like 使用的区别

    1.MySQL的复制相同表结构方法: 1)create table table_name as select * from table1 where 1=2 (或者limit  0): 2) crea ...

  2. Set a static file on django

    1. In setting file: ROOT_PATH='/home/ronglian/project/taskschedule' STATIC_URL = '/static/' STATICFI ...

  3. MSDE简介

    MSDE的全程是Microsoft SQL Server Desktop Engine,它是一个基于 SQL Server 核心技术构建的数据引擎.MSDE 2000 支持单处理器和双处理器,是面向小 ...

  4. Merge compare columns when null

    Key words: merge compare columns when we contact merge sql in ETL, When we update some columns we sh ...

  5. 用命令测试安装好的OpenStack环境

    OpenStack三个节点icehouse-gre模式部署一文部署了一套OpenStack环境,接下来使用命令测试一遍. 首先要明确几个概念: 外网:可分配floating ip绑定到虚拟机,外部就可 ...

  6. 《致命接触》:人畜共患传染病的故事,SARS一章非常精彩,四星推荐

    讲人畜共患的传染病的故事:亨德拉.埃博拉.疟疾.SARS.Q热.鹦鹉热.莱姆病.艾滋病等.作者比较会讲故事,又熟悉病毒传播相关的各种学科的知识(病毒学.生态学,还有一些我没记住的相关小学科),能把相关 ...

  7. 这一路走来,冷暖自知 (附算法demos)

    最近半年多,除了“一键修图”算法之外我还做了其他什么算法? 1.实时单图HDR算法(颜色矫正,智能曝光) 2.多图曝光融合HDR算法(最高支持八百万像素左右) 3.模拟热能探测算法 4.防伪探测算法 ...

  8. [cb] Unity Editor 添加右键菜单

    需求 为Unity的Editor窗口添加右键菜单 实现代码 // This example shows how to create a context menu inside a custom Edi ...

  9. java 13-3 int类型的包装包Integer

    1.Integer的概述 需求1:把100这个数据的二进制,八进制,十六进制计算出来 需求2:判断一个数据是否是int范围内的.  首先你得知道int的范围是多大? 为了对基本数据类型进行更多的操作, ...

  10. Java的IO操作---File类

    目标 1)掌握File类作用 2)可以使用file类中方法对文件进行读写操作. File类 唯一与文件有关的类.使用file类可进行创建或删除操作,要想使用File类,首先观察File类的构造方法. ...