search
HomeBackend DevelopmentPHP TutorialSymfony2 source code analysis - startup process 2, symfony2 source code_PHP tutorial

Symfony2 source code analysis - startup process 2, symfony2 source code

The previous article analyzed the Symfony2 framework source code and explored how Symfony2 completes the first half of a request. The first half can be understood as Symfony2 The framework prepares for processing requests, including container generation, caching, bundles initialization and other preparations (Symfony2 source code analysis - startup process 1). This article talks about how Symfony2 generates a Response object based on the requested data and returns the response data to the client.

Before analysis, you need to understand the event-driven mechanism of Symfony2: Symfony2 event-driven.

Closer to home, the workflow of Symfony2 requests is actually completed by the event driver of the Symfony2 kernel. The following are the kernel events defined by the Symfony2 framework:

Symfony2 source code analysis - startup process 2, symfony2 source code_PHP tutorialfinal class KernelEvents { /** * The REQUEST event occurs at the very beginning of request * dispatching * * This event allows you to create a response for a request before any * other code in the framework is executed. The event listener method * receives a SymfonyComponentHttpKernelEventGetResponseEvent * instance. * * @var string * * @api */ const REQUEST = 'kernel.request'; /** * The EXCEPTION event occurs when an uncaught exception appears * * This event allows you to create a response for a thrown exception or * to modify the thrown exception. The event listener method receives * a SymfonyComponentHttpKernelEventGetResponseForExceptionEvent * instance. * * @var string * * @api */ const EXCEPTION = 'kernel.exception'; /** * The VIEW event occurs when the return value of a controller * is not a Response instance * * This event allows you to create a response for the return value of the * controller. The event listener method receives a * SymfonyComponentHttpKernelEventGetResponseForControllerResultEvent * instance. * * @var string * * @api */ const VIEW = 'kernel.view'; /** * The CONTROLLER event occurs once a controller was found for * handling a request * * This event allows you to change the controller that will handle the * request. The event listener method receives a * SymfonyComponentHttpKernelEventFilterControllerEvent instance. * * @var string * * @api */ const CONTROLLER = 'kernel.controller'; /** * The RESPONSE event occurs once a response was created for * replying to a request * * This event allows you to modify or replace the response that will be * replied. The event listener method receives a * SymfonyComponentHttpKernelEventFilterResponseEvent instance. * * @var string * * @api */ const RESPONSE = 'kernel.response'; /** * The TERMINATE event occurs once a response was sent * * This event allows you to run expensive post-response jobs. * The event listener method receives a * SymfonyComponentHttpKernelEventPostResponseEvent instance. * * @var string */ const TERMINATE = 'kernel.terminate'; /** * The FINISH_REQUEST event occurs when a response was generated for a request. * * This event allows you to reset the global and environmental state of * the application, when it was changed during the request. * * @var string */ const FINISH_REQUEST = 'kernel.finish_request'; } View Code

  我们可以编写事件监听器,监听相应的内核事件,在Symfony2触发该事件的时候,相应的事件监听器就会执行。监听和唤醒形象的描述,就像,你(事件监听器)参加校运会,去大会(Symfony2)登记(监听)参加50米短跑(事件),当50米短跑比赛开始了(事件被触发),那你就奔跑吧(监听器执行,其实就是一个执行函数,函数完成什么工作就取决于你的需求了),少年。

  Symfony2的内核事件处理流程大部分工作都在HttpKernel::handleRaw方法中:

<span> 1</span>     <span>private</span> function handleRaw(Request $request, $type =<span> self::MASTER_REQUEST)
</span><span> 2</span> <span>    {
</span><span> 3</span>         $<span>this</span>->requestStack-><span>push($request);
</span><span> 4</span> 
<span> 5</span>         <span>//</span><span> request
</span><span> 6</span>         <span>//</span><span> 初始化事件,事件对象会被传递给监听器,所以事件可以说是一个信息的载体,事件内存放着监听器感兴趣的数据。</span>
<span> 7</span>         $<span>event</span> = <span>new</span> GetResponseEvent($<span>this</span><span>, $request, $type);
</span><span> 8</span>         <span>//</span><span> 触发kernel.request事件,后续详细讲解EventDispatcher::dispatch方法的实现,
</span><span> 9</span>         <span>//</span><span> 这里我们需要知道的是,dispatcher把$event传递给所有监听了kernel.request事件的监听器,监听器将会执行。
</span><span>10</span>         <span>//</span><span> kernel.request事件发生在controller执行之前,我们可以在这一步奏完成路由解析等为controller执行提供准备数据,
</span><span>11</span>         <span>//</span><span> 在这个过程允许我们直接生成Response对象,向客户端输出数据,那么controller就不会被执行了。</span>
<span>12</span>         $<span>this</span>->dispatcher->dispatch(KernelEvents::REQUEST, $<span>event</span><span>);
</span><span>13</span> 
<span>14</span>         <span>//</span><span> 如果我们在kernel.request事件生成了Response对象(响应数据),那么就跳过kernel.controller、kernel.view事件、
</span><span>15</span>         <span>//</span><span> controller也会被跳过,直接执行kernel.response事件。</span>
<span>16</span>         <span>if</span> ($<span>event</span>-><span>hasResponse()) {
</span><span>17</span>             <span>return</span> $<span>this</span>->filterResponse($<span>event</span>-><span>getResponse(), $request, $type);
</span><span>18</span> <span>        }
</span><span>19</span> 
<span>20</span>         <span>//</span><span> load controller
</span><span>21</span>         <span>//</span><span> 根据路由规则返回 一个对象或者数组或者字符串 ,如果$controller是一个数组,$controller[0]是存放的是要执行的controller对象,
</span><span>22</span>         <span>//</span><span> $controller[0]存放的是controller对象执行的方法,即action,方法的参数没有保存在$controller数组中;
</span><span>23</span>         <span>//</span><span> 如果$controller是对象,那么该对象就实现了__invoke 方法;
</span><span>24</span>         <span>//</span><span> 如果$controller是字符串,那么$controller就是要运行的函数的函数名。
</span><span>25</span>         <span>//</span><span> 图2是$controller的一个var_dump例子</span>
<span>26</span>         <span>if</span> (<span>false</span> === $controller = $<span>this</span>->resolver-><span>getController($request)) {
</span><span>27</span>             <span>throw</span> <span>new</span> NotFoundHttpException(sprintf(<span>'</span><span>Unable to find the controller for path "%s". Maybe you forgot to add the matching route in your routing configuration?</span><span>'</span>, $request-><span>getPathInfo()));
</span><span>28</span> <span>        }
</span><span>29</span> 
<span>30</span>         $<span>event</span> = <span>new</span> FilterControllerEvent($<span>this</span><span>, $controller, $request, $type);
</span><span>31</span>         <span>//</span><span> 触发kernel.controller事件,这个事件发生在controller执行前。我们可以通过监听这个事件在controller执行前修改controller,
</span><span>32</span>         <span>//</span><span> 或者完成一些动作。</span>
<span>33</span>         $<span>this</span>->dispatcher->dispatch(KernelEvents::CONTROLLER, $<span>event</span><span>);
</span><span>34</span>         $controller = $<span>event</span>-><span>getController();
</span><span>35</span> 
<span>36</span>         <span>//</span><span> controller arguments
</span><span>37</span>         <span>//</span><span> 从request对象中获取controller方法的参数</span>
<span>38</span>         $arguments = $<span>this</span>->resolver-><span>getArguments($request, $controller);
</span><span>39</span> 
<span>40</span>         <span>//</span><span> call controller
</span><span>41</span>         <span>//</span><span> 执行controller</span>
<span>42</span>         $response =<span> call_user_func_array($controller, $arguments);
</span><span>43</span> 
<span>44</span>         <span>//</span><span> view
</span><span>45</span>         <span>//</span><span> 如果$response不是Response对象,那么kernel.view事件就会触发,监听kernel.view事件的监听器通过$response值生成Response对象。</span>
<span>46</span>         <span>if</span> (!<span>$response instanceof Response) {
</span><span>47</span>             $<span>event</span> = <span>new</span> GetResponseForControllerResultEvent($<span>this</span><span>, $request, $type, $response);
</span><span>48</span>             $<span>this</span>->dispatcher->dispatch(KernelEvents::VIEW, $<span>event</span><span>);
</span><span>49</span> 
<span>50</span>             <span>if</span> ($<span>event</span>-><span>hasResponse()) {
</span><span>51</span>                 $response = $<span>event</span>-><span>getResponse();
</span><span>52</span> <span>            }
</span><span>53</span> 
<span>54</span>             <span>if</span> (!<span>$response instanceof Response) {
</span><span>55</span>                 $msg = sprintf(<span>'</span><span>The controller must return a response (%s given).</span><span>'</span>, $<span>this</span>-><span>varToString($response));
</span><span>56</span> 
<span>57</span>                 <span>//</span><span> the user may have forgotten to return something</span>
<span>58</span>                 <span>if</span> (<span>null</span> ===<span> $response) {
</span><span>59</span>                     $msg .= <span>'</span><span> Did you forget to add a return statement somewhere in your controller?</span><span>'</span><span>;
</span><span>60</span> <span>                }
</span><span>61</span>                 <span>throw</span> <span>new</span><span> \LogicException($msg);
</span><span>62</span> <span>            }
</span><span>63</span> <span>        }
</span><span>64</span> 
<span>65</span>         <span>//</span><span> 触发kernel.response事件,在向客户端输出Response对象前,我们可以对Response对象进行修改,
</span><span>66</span>         <span>//</span><span> 例如修改response头部,设置缓存、压缩输出数据等。
</span><span>67</span> 
<span>68</span>         <span>//</span><span> 接着触发kernel.finish_request事件,把当前请求从请求栈中弹出,当前请求就完成。</span>
<span>69</span>         <span>return</span> $<span>this</span>-><span>filterResponse($response, $request, $type);
</span><span>70</span> 
<span>71</span>         <span>//</span><span> 千万别忘记了,filterResponse执行完后,Symfony2内核事件处理流程还有最后一步,位于app_dev.php[app.php]最后一行,
</span><span>72</span>         <span>//</span><span> $kernel->terminate($request, $response);这个方法触发kernel.terminate事件,此时,Symfony2已经响应了客户端的请求,
</span><span>73</span>         <span>//</span><span> 向客户端输出了Response对象。监听kernel.terminate事件的监听器,主要是为了完成一些耗时的操作,操作的结果不需要返回给
</span><span>74</span>         <span>//</span><span> 客户端的,例如邮件发送、图片压缩等等。
</span><span>75</span>         <span>//</span><span> 到这里,Symfony2的整个流程就走完了。</span>
<span>76</span>     }
<span>HttpKernel::filterResponse方法和</span>HttpKernel::finishRequest方法:
Symfony2 source code analysis - startup process 2, symfony2 source code_PHP tutorial 1 private function filterResponse(Response $response, Request $request, $type) 2 { 3 $event = new FilterResponseEvent($this, $request, $type, $response); 4 5 $this->dispatcher->dispatch(KernelEvents::RESPONSE, $event); 6 7 $this->finishRequest($request, $type); 8 9 return $event->getResponse(); 10 } 11 12 /** 13 * Publishes the finish request event, then pop the request from the stack. 14 * 15 * Note that the order of the operations is important here, otherwise 16 * operations such as {@link RequestStack::getParentRequest()} can lead to 17 * weird results. 18 * 19 * @param Request $request 20 * @param int $type 21 */ 22 private function finishRequest(Request $request, $type) 23 { 24 $this->dispatcher->dispatch(KernelEvents::FINISH_REQUEST, new FinishRequestEvent($this, $request, $type)); 25 $this->requestStack->pop(); 26 } View Code

图2

Symfony2框架的事件分发机制的核心代码:

<span> 1</span>     <span>public</span> function dispatch($eventName, Event $<span>event</span> = <span>null</span><span>)
</span><span> 2</span> <span>    {
</span><span> 3</span>         <span>if</span> (<span>null</span> === $<span>event</span><span>) {
</span><span> 4</span>             $<span>event</span> = <span>new</span><span> Event();
</span><span> 5</span> <span>        }
</span><span> 6</span> 
<span> 7</span>         $<span>event</span>->setDispatcher($<span>this</span><span>);
</span><span> 8</span>         $<span>event</span>-><span>setName($eventName);
</span><span> 9</span> 
<span>10</span>         <span>if</span> (!isset($<span>this</span>-><span>listeners[$eventName])) {
</span><span>11</span>             <span>return</span> $<span>event</span><span>;
</span><span>12</span> <span>        }
</span><span>13</span> 
<span>14</span>         <span>//</span><span> $eventName即:KernelEvents::REQUEST、KernelEvents::CONTROLLER、KernelEvents::VIEW、KernelEvents::RESPONSE、KernelEvents::TERMINATE等
</span><span>15</span>         <span>//</span><span> getListeners返回所有监听$eventName事件的监听器</span>
<span>16</span>         $<span>this</span>->doDispatch($<span>this</span>->getListeners($eventName), $eventName, $<span>event</span><span>);
</span><span>17</span> 
<span>18</span>         <span>return</span> $<span>event</span><span>;
</span><span>19</span> <span>    }
</span><span>20</span> 
<span>21</span>     <span>protected</span> function doDispatch($listeners, $eventName, Event $<span>event</span><span>)
</span><span>22</span> <span>    {
</span><span>23</span>         <span>//</span><span> 监听器执行</span>
<span>24</span>         <span>foreach</span> ($listeners <span>as</span><span> $listener) {
</span><span>25</span>             call_user_func($listener, $<span>event</span>, $eventName, $<span>this</span><span>);
</span><span>26</span>             <span>//</span><span> 如果其中一个监听器把$event的propagationStopped属性设置为true,那么表示$eventName这一事件终止执行,
</span><span>27</span>             <span>//</span><span> 事件不会往$listeners里尚未执行的监听器传递该事件。</span>
<span>28</span>             <span>if</span> ($<span>event</span>-><span>isPropagationStopped()) {
</span><span>29</span>                 <span>break</span><span>;
</span><span>30</span> <span>            }
</span><span>31</span> <span>        }
</span><span>32</span>     }

 

有没有哪本书具体讲linux内核启动过程的,详细点的(最好具体到实际代码),最好内核针对于26以后的

我个人感觉毛德操先生的书linux内核情景分析,分析的很透彻的,对整个Linux内核的讲解很不错.具体到启动过程,这个启动过程很泛的,你只需要知道整体的启动过程,其他的细节,还得看内核源码讲解,所以,推荐你看点博客了解下启动大体过程,具体到每个细节,看linux内核情景分析吧.
 

android 21的源码分析之长按电源键弹出对话框功可以更改

1.这个dialog是由PhoneWindowManager控制的,在PhoneWindowManager的interceptKeyTq方法中,代码是这一行

mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());

mProwerLongPress是一个Runnable,执行时调用GlobalActions中的showDialog方法。所以这个dialog是由GlobalActions管理的,PowerDialog是之前版本中的,现在已经弃用了。

2.可以在GlobalActions中createDialog方法中mSilentModeToggle action的onToggle方法中加入

mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, on ? AudioManager.VIBRATE_SETTING_ON : AudioManager.VIBRATE_SETTING_OFF);

这一句,仿照铃声的处理,应该没问题,不过没试所以也不能确定。

希望对你有帮助。
 

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/899447.htmlTechArticleSymfony2源码分析——启动过程2,symfony2源码 上一篇分析Symfony2框架源码,探究Symfony2如何完成一个请求的前半部分,前半部分可以理解为Sy...
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
The Continued Use of PHP: Reasons for Its EnduranceThe Continued Use of PHP: Reasons for Its EnduranceApr 19, 2025 am 12:23 AM

What’s still popular is the ease of use, flexibility and a strong ecosystem. 1) Ease of use and simple syntax make it the first choice for beginners. 2) Closely integrated with web development, excellent interaction with HTTP requests and database. 3) The huge ecosystem provides a wealth of tools and libraries. 4) Active community and open source nature adapts them to new needs and technology trends.

PHP and Python: Exploring Their Similarities and DifferencesPHP and Python: Exploring Their Similarities and DifferencesApr 19, 2025 am 12:21 AM

PHP and Python are both high-level programming languages ​​that are widely used in web development, data processing and automation tasks. 1.PHP is often used to build dynamic websites and content management systems, while Python is often used to build web frameworks and data science. 2.PHP uses echo to output content, Python uses print. 3. Both support object-oriented programming, but the syntax and keywords are different. 4. PHP supports weak type conversion, while Python is more stringent. 5. PHP performance optimization includes using OPcache and asynchronous programming, while Python uses cProfile and asynchronous programming.

PHP and Python: Different Paradigms ExplainedPHP and Python: Different Paradigms ExplainedApr 18, 2025 am 12:26 AM

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

PHP and Python: A Deep Dive into Their HistoryPHP and Python: A Deep Dive into Their HistoryApr 18, 2025 am 12:25 AM

PHP originated in 1994 and was developed by RasmusLerdorf. It was originally used to track website visitors and gradually evolved into a server-side scripting language and was widely used in web development. Python was developed by Guidovan Rossum in the late 1980s and was first released in 1991. It emphasizes code readability and simplicity, and is suitable for scientific computing, data analysis and other fields.

Choosing Between PHP and Python: A GuideChoosing Between PHP and Python: A GuideApr 18, 2025 am 12:24 AM

PHP is suitable for web development and rapid prototyping, and Python is suitable for data science and machine learning. 1.PHP is used for dynamic web development, with simple syntax and suitable for rapid development. 2. Python has concise syntax, is suitable for multiple fields, and has a strong library ecosystem.

PHP and Frameworks: Modernizing the LanguagePHP and Frameworks: Modernizing the LanguageApr 18, 2025 am 12:14 AM

PHP remains important in the modernization process because it supports a large number of websites and applications and adapts to development needs through frameworks. 1.PHP7 improves performance and introduces new features. 2. Modern frameworks such as Laravel, Symfony and CodeIgniter simplify development and improve code quality. 3. Performance optimization and best practices further improve application efficiency.

PHP's Impact: Web Development and BeyondPHP's Impact: Web Development and BeyondApr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

How does PHP type hinting work, including scalar types, return types, union types, and nullable types?How does PHP type hinting work, including scalar types, return types, union types, and nullable types?Apr 17, 2025 am 12:25 AM

PHP type prompts to improve code quality and readability. 1) Scalar type tips: Since PHP7.0, basic data types are allowed to be specified in function parameters, such as int, float, etc. 2) Return type prompt: Ensure the consistency of the function return value type. 3) Union type prompt: Since PHP8.0, multiple types are allowed to be specified in function parameters or return values. 4) Nullable type prompt: Allows to include null values ​​and handle functions that may return null values.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools