首頁  >  文章  >  後端開發  >  Symfoy2源码分析——启动过程1,symfoy2源码_PHP教程

Symfoy2源码分析——启动过程1,symfoy2源码_PHP教程

WBOY
WBOY原創
2016-07-13 10:17:071043瀏覽

Symfoy2源码分析——启动过程1,symfoy2源码

    本文通过阅读分析Symfony2的源码,了解Symfony2启动过程中完成哪些工作,从阅读源码了解Symfony2框架。

    Symfony2的核心本质是把Request转换成Response的一个过程。

    我们大概看看入口文件(web_dev.php)的源码,入口文件从总体上描述了Symfony2框架的工作的流程:

<span> 1</span> require_once __DIR__.<span>'</span><span>/../app/AppKernel.php</span><span>'</span><span>;
</span><span> 2</span> 
<span> 3</span> $kernel = <span>new</span> AppKernel(<span>'</span><span>dev</span><span>'</span>, <span>true</span><span>);
</span><span> 4</span> $kernel-><span>loadClassCache();
</span><span> 5</span> <span>//</span><span>利用请求信息($_GET $_POST $_SERVER等等)构造Request对象</span>
<span> 6</span> $request =<span> Request::createFromGlobals();
</span><span> 7</span> <span>//</span><span>Symfony2框架核心工作就是把Request对象转换成Response对象</span>
<span> 8</span> $response = $kernel-><span>handle($request);
</span><span> 9</span> <span>//</span><span>向客户端输出Response对象</span>
<span>10</span> $response-><span>send();
</span><span>11</span> <span>//</span><span>完成一些耗时的后台操作,例如邮件发送,图片裁剪等等耗时工作</span>
<span>12</span> $kernel->terminate($request, $response);

    Symfony2框架通过客户端的请求信息来决定生成并返回响应的数据,我们下面的Symfony2源码分析重点就是AppKernel::handle方法。

 

    AppKernel::handle的实现继承于Kernel::handle

<span> 1</span>     <span>/*</span><span>*
</span><span> 2</span> <span>     *
</span><span> 3</span> <span>     * @param Request $request Request对象实例
</span><span> 4</span> <span>     * @param int     $type    请求的类型(子请求 or 主请求)
</span><span> 5</span> <span>     * @param bool    $catch   是否捕捉异常
</span><span> 6</span> <span>     *
</span><span> 7</span> <span>     * @return Response Response对象实例
</span><span> 8</span> <span>     *
</span><span> 9</span>      <span>*/</span>    
<span>10</span>     <span>public</span> function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $<span>catch</span> = <span>true</span><span>)
</span><span>11</span> <span>    {   
</span><span>12</span>         <span>//</span><span>$this->booted Symfony2框架只启动一次</span>
<span>13</span>         <span>if</span> (<span>false</span> === $<span>this</span>-><span>booted) {
</span><span>14</span>             <span>//</span><span>初始化并启动所有注册在AppKernel里面的所有bundles(AppKernel::registerBundles)
</span><span>15</span>             <span>//</span><span>初始化container
</span><span>16</span>             <span>//</span><span>加载、缓存配置数据和路由数据、编译container容器等,为后面事件处理做准备。</span>
<span>17</span>             $<span>this</span>-><span>boot();
</span><span>18</span> <span>        }
</span><span>19</span> 
<span>20</span>         <span>//</span><span>开启事件处理,Symfony2内核的请求处理过程本质是一系列的事件处理过程</span>
<span>21</span>         <span>return</span> $<span>this</span>->getHttpKernel()->handle($request, $type, $<span>catch</span><span>);
</span><span>22</span>     }

    AppKernel::boot方法

<span> 1</span>     <span>public</span><span> function boot()
</span><span> 2</span> <span>    {
</span><span> 3</span>         <span>if</span> (<span>true</span> === $<span>this</span>-><span>booted) {
</span><span> 4</span>             <span>return</span><span>;
</span><span> 5</span> <span>        }
</span><span> 6</span> 
<span> 7</span>         <span>if</span> ($<span>this</span>-><span>loadClassCache) {
</span><span> 8</span>             $<span>this</span>->doLoadClassCache($<span>this</span>->loadClassCache[<span>0</span>], $<span>this</span>->loadClassCache[<span>1</span><span>]);
</span><span> 9</span> <span>        }
</span><span>10</span> 
<span>11</span>         <span>//</span><span> init bundles
</span><span>12</span>         <span>//</span><span>初始化注册到AppKernel里的所有bundle(AppKernel::registerBundles)</span>
<span>13</span>         $<span>this</span>-><span>initializeBundles();
</span><span>14</span> 
<span>15</span>         <span>//</span><span> init container
</span><span>16</span>         <span>//</span><span>初始化并编译缓存container,包括载入配置信息、编译信息、service等
</span><span>17</span>         <span>//</span><span>Symfony2的核心组件的加载,和各个组件之间的关联关系都在container容器初始化中完成,所以这会是下面详细描述</span>
<span>18</span>         $<span>this</span>-><span>initializeContainer();
</span><span>19</span> 
<span>20</span>         <span>//</span><span>把bundle注入到container,并启动bundle</span>
<span>21</span>         <span>foreach</span> ($<span>this</span>->getBundles() <span>as</span><span> $bundle) {
</span><span>22</span>             $bundle->setContainer($<span>this</span>-><span>container);
</span><span>23</span>             $bundle-><span>boot();
</span><span>24</span> <span>        }
</span><span>25</span> 
<span>26</span>         <span>//</span><span>标记Symfony2只启动一次并启动成功</span>
<span>27</span>         $<span>this</span>->booted = <span>true</span><span>;
</span><span>28</span>     }

    AppKernel::initializeContainer源码解析

<span> 1</span>     <span>protected</span><span> function initializeContainer()
</span><span> 2</span> <span>    {
</span><span> 3</span>         <span>//</span><span>检查app/cache/dev[prod]缓存文件是否过期,以container缓存文件的最后修改时间为参考时间,
</span><span> 4</span>         <span>//</span><span>如果app/cache/dev[prod]下的存在一个或者多个缓存文件的最后修改时间大于container缓存文件的
</span><span> 5</span>         <span>//</span><span>最后修改时间,就判断为缓存过期。
</span><span> 6</span>         <span>//</span><span>另外,如果$this->debug为false(即关闭debug的情况下)只要container缓存文件存在,那么就认为
</span><span> 7</span>         <span>//</span><span>缓存不过期</span>
<span> 8</span>         $<span>class</span> = $<span>this</span>-><span>getContainerClass();
</span><span> 9</span>         $cache = <span>new</span> ConfigCache($<span>this</span>->getCacheDir().<span>'</span><span>/</span><span>'</span>.$<span>class</span>.<span>'</span><span>.php</span><span>'</span>, $<span>this</span>-><span>debug);
</span><span>10</span>         $fresh = <span>true</span><span>;
</span><span>11</span>         <span>if</span> (!$cache-><span>isFresh()) {
</span><span>12</span>             <span>//</span><span>初始化一个ContainerBuilder对象实例;
</span><span>13</span>             <span>//</span><span>自动加载所有注册的Bundle的DependencyInjection下的所有extension,Bundle可以通过extension来加载属于该Bundle配置(service的配置、
</span><span>14</span>             <span>//</span><span>路由的配置等等)、Bundle的全局变量等
</span><span>15</span>             <span>//</span><span>同时这些extension加载的信息都会被保存到container中;
</span><span>16</span>             <span>//</span><span>加载并保存compiler pass到container,为下一步compile做准备,我们可以通过compiler pass修改已经注册到container的service的属性
</span><span>17</span>             <span>//</span><span>compiler pass的官方文档http:</span><span>//</span><span>symfony.com/doc/current/cookbook/service_container/compiler_passes.html</span>
<span>18</span>             $container = $<span>this</span>-><span>buildContainer();
</span><span>19</span>             <span>//</span><span>执行compiler pass 的process方法,container的compile过程主要是执行上一步保存到container内的compiler pass 的process方法</span>
<span>20</span>             $container-><span>compile();
</span><span>21</span>             <span>//</span><span>生成container的缓存(appDevDebugProjectContainer.php),该container包含了service的获取方法、别名的映射关系</span>
<span>22</span>             $<span>this</span>->dumpContainer($cache, $container, $<span>class</span>, $<span>this</span>-><span>getContainerBaseClass());
</span><span>23</span> 
<span>24</span>             $fresh = <span>false</span><span>;
</span><span>25</span> <span>        }
</span><span>26</span> 
<span>27</span>         
<span>28</span> <span>        require_once $cache;
</span><span>29</span> 
<span>30</span>         $<span>this</span>->container = <span>new</span> $<span>class</span><span>();
</span><span>31</span>         $<span>this</span>->container-><span>set</span>(<span>'</span><span>kernel</span><span>'</span>, $<span>this</span><span>);
</span><span>32</span> 
<span>33</span>         <span>//</span><span>...............</span>
<span>34</span>         <span>if</span> (!$fresh && $<span>this</span>->container->has(<span>'</span><span>cache_warmer</span><span>'</span><span>)) {
</span><span>35</span>             $<span>this</span>->container-><span>get</span>(<span>'</span><span>cache_warmer</span><span>'</span>)->warmUp($<span>this</span>->container->getParameter(<span>'</span><span>kernel.cache_dir</span><span>'</span><span>));
</span><span>36</span> <span>        }
</span><span>37</span>     }
<span> 1</span>     <span>protected</span><span> function prepareContainer(ContainerBuilder $container)
</span><span> 2</span> <span>    {
</span><span> 3</span>         $extensions =<span> array();
</span><span> 4</span>         <span>foreach</span> ($<span>this</span>->bundles <span>as</span><span> $bundle) {
</span><span> 5</span>             <span>//</span><span>加载DependencyInjection下的Extension,所有Extension必需实现Extension接口</span>
<span> 6</span>             <span>if</span> ($extension = $bundle-><span>getContainerExtension()) {
</span><span> 7</span>                 $container-><span>registerExtension($extension);
</span><span> 8</span>                 $extensions[] = $extension-><span>getAlias();
</span><span> 9</span> <span>            }
</span><span>10</span> 
<span>11</span>             <span>//</span><span>开启debug的情况下,把bundles添加到recourses</span>
<span>12</span>             <span>if</span> ($<span>this</span>-><span>debug) {
</span><span>13</span>                 $container-><span>addObjectResource($bundle);
</span><span>14</span> <span>            }
</span><span>15</span> <span>        }
</span><span>16</span>         <span>foreach</span> ($<span>this</span>->bundles <span>as</span><span> $bundle) {
</span><span>17</span>             <span>//</span><span>通常用来添加compiler pass</span>
<span>18</span>             $bundle-><span>build($container);
</span><span>19</span> <span>        }
</span><span>20</span> 
<span>21</span>         <span>//</span><span> ensure these extensions are implicitly loaded</span>
<span>22</span>         $container->getCompilerPassConfig()->setMergePass(<span>new</span><span> MergeExtensionConfigurationPass($extensions));
</span><span>23</span>     }

    从AppKernel::initializeContainer可以看出Bundle和container是Symfony2框架的基础核心,container是Symfony2框架的所有组件的统一管理中心,Bundle就是一个功能模块的组织。

    如果你好奇service、配置参数是怎样被加载的,可以详细去了解Symfony2的Extension;如果你好奇怎么对已经加载了的service进一步完善和修改,可有详细了解Symfony2的compiler pass。

    到了这一步,Symfony2框架启动几乎完成,为后面的内核事件处理EventDispatcher::dispatch做好了准备。

    下一篇讲解Symfony2框架的内核事件处理。

 

易语言怎写一个源码,使得可以通过控制窗口1内的按钮,来控制启动窗口的属性变换,比如换肤,



这是用按钮点击事件进行变换皮肤,如果放在启动窗口下面回出现每次打开皮肤会不一样的。

Symfoy2源码分析——启动过程1,symfoy2源码_PHP教程
 

谁可以给我一个怎使我编的软件随机启动的易语言源码?

用下面这个代码就可以了,很简单的,

写注册项(3,“software\microsoft\windows\CurrentVersion\Run\我的启动项”,“你程序所在的目录+文件名”)
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/894763.htmlTechArticleSymfoy2源码分析——启动过程1,symfoy2源码 本文通过阅读分析Symfony2的源码,了解Symfony2启动过程中完成哪些工作,从阅读源码了解Symfony2框架...
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn