## app/config/ 下 parameter.yml # 因爲參數敏感,該文件被版本控制系統忽略 parameter.yml.dist # 在parameter.yml中定義的參數須要也在這裏添加,該文件是它的配置模板 # 每次部署,該文件會與之比對,若有差別,symfony會要求提供新參數在parameter.yml中
$request = Request::createFromGlobals(); $request->isXmlHttpRequest(); ->getMethod(); ->query->get('var', 'default'); ->request->get(); ->files->get(); ->cookies->get(); ->server->get(); ->headers->get(); ->getSession(); ->isSecure(); //斷定https ->attributes->get('_controller, _route, {id} ....'); ->getRequestFormat(); ->getContent(); parameter bags通用方法 ->get(); ->has(); ->all();
$response = new Response($content, $Response::HTTP_OK); //Response::HTTP_NOT_FOUND $response->setStatusCode(Response::HTTP_OK); ->headers->set('Content-Type', 'text/html'); ->setContent('<html><body><h1>Hello world!</h1></body></html>'); ->send(); JsonResponse, BinaryFileResponse. 頁面報錯: 400 - throw Controller->createNotFoundException(); 500 - throw new \Exception('Something wrong!'); FlashMessage: Controller->addFlash('notice', 'Congratulations, your action succeeded!'); <div> {{ app.session.flashbag.get('notice') }} </div>
框架自帶組件:Serializer 第三方bundle:JMSSerializerBundle 啓用序列化組件(服務啓用後默認配備JsonEncoder和XmlEncoder,但沒有標準化器 normalizers) # app/config/config.yml framework: serializer: enabled: true 給服務打tag以標註其爲normalizer或encoder, 從而在序列化載入時一塊兒載入它們 # app/config/config.yml services: get_set_method_normalizer: class: Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer tags: - { name: serializer.normalizer } #使用序列化時僅需配置序列化器的可用服務: $encoders = array(new XmlEncoder(), new JsonEncoder()); $normalizers = array(new GetSetMethodNormalizer()); $serializer = new Serializer($normalizers, $encoders); $person = new Acme\Person(); $jsonContent = $serializer->serialize($person, 'json'); //第二參指定encoder #忽略部分部分屬性的序列化 $normalizer = new GetSetMethodNormalizer(); $normalizer->setIgnoredAttributes(array('age')); #反序列化 $data = "<person><name>foo</name><age>99</age><sportsman>false</sportsman></person>"; $person = $serializer->deserialize($data, 'Acme\Person', 'xml'); #第二參指定需生成的類, 第三參指定encoder
sensio/framework-extra-bundle #提供在控制器中註解命令的支持,自帶 jms/di-extra-bundle #提供註解命令實現屬性注入的支持 doctrine/doctrine-fixtures-bundle #提供data fixture支持
php app/console generate:bundle ------ bundle目錄 |-AppKernel->registerBundles(); //內核註冊Bundle |-app/config/routing.yml; //路由配置 |-app/config/config.yml; //Bundle配置 bundle路徑格式: @BUNDLE_NAME/path/to/file //註解命令索引bundle文件 BUNDLE_NAME:CONTROLLER_NAME:ACTION_NAME //索引action操做
1.composer安裝bundle 2.內核註冊啓用bundle 3.配置bundle(app/config/config.yml及bundle內配置文件) app/console config:dump-reference AsseticBundle //dump出bundle配置幫助 bundle/Resource/doc/index.md //bundle配置幫助文件
dump($articles); //控制器調試 {{ dump(articles) }} //模板調試(必須TwigBundle的debug配置爲true) debug toolbar 只有在render()調用事後纔會顯示
1.安裝apc字節碼緩存拓展, 並關閉文件檢查php.ini => apc.stat=0 轉爲手動管理 代碼更新 引發的 apc緩存失效 2.web/app.php 打開 ApcClassLoader 3.使用引導文件 web/app.php 啓用 require_once __DIR__.'/../app/bootstrap.php.cache' //類定義聚合文件 4.使用http反向代理緩存系統AppCache或者專業的Varnish, Squid等
常常使用的類 及 被其餘服務依賴的類 能夠註冊爲服務
php
服務配置: services: service_name: public: bool, #false時, 該服務僅能用於配置定義依賴, 不能再容器中取出 class: Acme\HelloBundle\Mailer arguments: [] file: %kernel.root_dir%/src/path/to/file/foo.php #加載服務前提依賴文件 tags: - {name: xxx} # 通常的, service_name會定義爲目錄名加類名,從而避免同名衝突, 如這裏的:acme.hello.mailer # 固然, 其餘合理的短名稱也是能夠的 容器調用: $controller->get($service_name); YAML格式的數組參數定義: 方式1: 數組括號【】 方式2: 前導橫線 「- {item1}「 YAML文件導入外部資源: 方式1: imports命令 imports: - { resource: "@AcmeHelloBundle/Resources/config/services.yml" } 方式2: 使用服務拓展類導入配置 ServiceContainer配置: services: my_mailer: # ... newsletter_manager: class: Acme\HelloBundle\Newsletter\NewsletterManager arguments: [無引號string參數,@my_mailer, @?my_mailer, "@=service('mailer_configuration').getMailerMethod()"] #申明一個依賴(構造函數注入), 申明一個可選依賴(構造函數注入, 參數須帶默認值), 申明依賴一個表達式值 calls: - [setMailer, ["@my_mailer"]] #申明可選依賴(setter注入) 服務別名($container->get('bar'); ): services: foo: class: Acme\HelloBundle\Foo bar: alias: foo
標準化並集中管理對象的初始化 ############ 原始類 ############# class Mailer{ private $transport; public function __construct($transport) { $this->transport = $transport; } } class NewsletterManager{ private $mailer; public function __construct(\Mailer $mailer) { $this->mailer = $mailer; } public function setMailer(\Mailer $mailer) { $this->mailer = $mailer; } } ########## AAAAAA ########### ## PHP代碼來註冊服務 use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; $container = new ContainerBuilder(); $container->setParameter('mailer.transport', 'sendmail'); $container ->register('mailer', 'Mailer') ->addArgument('%mailer.transport%'); //或者直接傳參 ->addArgument('sendmail'); $container ->register('newsletter_manager', 'NewsletterManager') ->addArgument(new Reference('mailer')); //構造函數注入 $container ->register('newsletter_manager', 'NewsletterManager') ->addMethodCall('setMailer', array(new Reference('mailer'))); //setter注入 ######## BBBBBB ########## ## 加載配置文件來註冊服務 use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; $container = new ContainerBuilder(); $loader = new YamlFileLoader($container, new FileLocator(__DIR__)); $loader->load('services.yml'); ######## CCCCCC ########## ## 直接在配置文件中註冊服務(即服務容器配置) ################################ ####### 得到容器中的服務 ######## use Symfony\Component\DependencyInjection\ContainerBuilder; $container = new ContainerBuilder(); $newsletterManager = $container->get('newsletter_manager');
## 前端控制器 $kernel = new AppKernel('環境', '是否debug模式'); 框架層次: FrameworkBundle ^ HttpKernel 處理http動態部分 ^ HttpFoundation 最底層, 抽象出了一組http處理的對象 內核依賴ControllerResolverInterface的一個實現來選擇合適的控制器, 接口聲明瞭兩個方法: public function getController(Request $request); //默認將經過RouterListener去定義了Request::_controller屬性(相似於Bundle\BlogBundle\PostController:indexAction), 最後返回callable形式的controller public function getArguments(Request $request, $controller); //默認在Requestion屬性中尋找(同名匹配action須要的參數) AppKernel::handle(Request, RequestType, EnableException)的內部實現依賴Resolver和一組有序時間通知鏈 從而 將 請求 轉爲 響應 應用生命週期, HttpKernel拋出KernelEvents事件,監聽器收到相應事件類: 1.kernel.request,事件類GetResponseEvent. 在request dispatching的最初時拋出 此處可在框架流程開始前就返回響應(任意相關監聽器經過setResponse方法在Event上寫入Response。若是有監聽器返回了Response, 則後續監聽器直接略過, 直接跳8) 通常的FrameworkBundle此處經過RouteListener計算Request::_controller。 通常掛載在此處的監聽器須要判斷下$event->isMasterRequest(), 避免響應內部子請求。 | V 2.調用Resolver來找到Controller(callable形式) | V 3.kernel.controller,事件類FilterControllerEvent. 當請求匹配到controller時拋出 可在此處切換控制器 | V 4.kernel檢查Controller是有效callable | V 5.調用Resolver來找到參數傳給Controller | V 6.Kernel正式調用Controller | V 7.kernel.view,事件類GetResponseForControllerResultEvent,當Controller返回非Response實例時拋出 此處可爲controller返回值建立response(監聽器獲取原始值$event->getControllerResult()並將其轉化爲Response) | V 8.kernel.response,事件類FilterResponseEvent, 當針對請求建立了response時拋出 此處可調整或替換response(獲取響應$event->getResponse()) | V 9.返回Response | V 10.kernel.finish_request, 事件類FinishRequestEvent,當針對請求生成好http響應時拋出 若是請求致使調整了應用環境狀態,可在此處理, 不管成功或異常都會執行到這 | V 11.kernel.terminate,事件類PostResponseEvent,當response送出後拋出 可作些收尾工做 kernel.exception,事件類GetResponseForExceptionEvent,當應用內部未能捕獲掉異常時拋出 此處可處理異常拋出後如何響應或進一步調整異常。異常處理成功, 則進入8。失敗, 則將異常從新拋出。 FramworkBundle註冊了ExceptionListener來將請求引導到特定控制器 在內部請求處理時, 不但願捕獲異常, 可在handle()方法第三參傳false來關閉kernel.exception事件. 監聽器處理 kernel.request, kernel.view or kernel.exception 時, 設定了response後, 事件再也不傳遞, 於是這些事件的低優先級監聽器不會被調用到 ############################################################################################################################################################# FramworkBundle註冊了以下監聽器: ProfilerListener 從當前Request中收集數據 WebDebugToolbarListener 注入web調試工具條 ResponserListener 填寫響應的content-type信息 EsiListener 添加一個代理控制http頭,若是響應存在Esi標籤 事件調試: app/console debug:event-dispatcher 【事件名】 內部請求: 每次主請求期間能夠執行子請求, 在handle()第二參傳入請求類型RequestType HttpKernelInterface::MASTER_REQUEST; HttpKernelInterface::SUB_REQUEST; 事件: Kernel可用Event都繼承自KernelEvent. KernelEvent ->getRequestType(); ->isMasterRequest(); ->getKernel(); ->getRequest(); 獲取調試信息: $profile = $container->get('profiler')->loadProfileFromResponse($response); $profile = $container->get('profiler')->loadProfile($token); 導出導入調試信息: $data = $profiler->export($profile); $profiler->import($data); 獲取調試token(也保存在http響應頭X-Debug-Token): $tokens = $container->get($host_ip, $url_pattern, $latest_count, $time_begin, $time_end);
symfony自帶許多事件、鉤子 由 HttpKernel 組件拋出(定義在KernelEvents類中) 監聽事件流程: 1. 建立事件監聽器 class AcmeExceptionListener { public function onKernelException(GetResponseForExceptionEvent $event) { $exception = $event->getException(); if ($exception instanceof HttpExceptionInterface) {} //.... $event->setResponse($response); //對象上設定response(對象是傳引用) } } 2. 監聽器註冊爲服務, 並綁定到事件 # app/config/services.yml services: kernel.listener.your_listener_name: class: AppBundle\EventListener\AcmeExceptionListener tags: - { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: xxx } #priority參數可選, 默認爲0, 範圍-255 ~ 255, 監聽器從大到小值調用