你还可以通过settings.yml文件达到此目的,修改web_deug、use_security、cache和use_flash的设置即可,应为每一个默认过滤器都有一个condition参数来自上面的配置。
② 不要通过删除filters.yml文件中的过滤器来禁用该过滤器,symfony将抛出异常
③ 可以自定义过滤器,但无论如何rendering必须是第一个,而execution必须是最后一个
④ 为默认过滤器重写默认类和参数(特别是修改security系统和用户的安全验证过滤器)
创建自定义过滤器
通过创建myFilter的类可以非常简单的常见自定义的过滤器,把类文件放在项目的lib文件夹可以充分利用symfony提供的自动加载特性。
由于动作之间可以互相跳转,因此过滤器链会在每一个请求中循序执行。但更多的时候可能需要是第一次请求的时候执行自定义的过滤器,这时候使用sfFilter类的isFirstCall()方法。看下面代码:apps/myapp/lib/rememberFilter.class.php(例子)
class rememberFilter extends sfFilter { public function execute($filterChain) { // 通过调用isFirstCall方法保证只执行一次 if ($this->isFirstCall()) { // 过滤器不直接访问请求和用户对象,你需要使用context对象获取 // You will need to use the context object to get them $request = $this->getContext()->getRequest(); $user = $this->getContext()->getUser(); if ($request->getCookie('MyWebSite')) { // 登入 $user->setAuthenticated(true); } } // 执行下一个过滤器 $filterChain->execute(); } }
有时候需要在一个过滤器执行之后跳往另一个动作而不是下一个过滤器。sfFilter不包含forward方法,但sfController包含,使用下面的语句:
return $this->getContext()->getController()->forward('mymodule', 'myAction');
sfFilter类有一个initialize方法,在对象创建的时候执行,可以在自定义的过滤器中覆盖此方法以达到更加灵活地设置参数的目的。
过滤器激活及参数
过滤器创建后还必须进行激活,在apps/myapp/config/filters.yml文件中:
rendering: ~ web_debug: ~ security: ~ remember: # Filters need a unique name class: rememberFilter param: cookie_name: MyWebSite condition: %APP_ENABLE_REMEMBER_ME% cache: ~ common: ~ flash: ~ execution: ~
自定义过滤器中的参数可以在过滤器代码中使用getParameter方法获取:
apps/myapp/lib/rememberFilter.class.php
class rememberFilter extends sfFilter { public function execute ($filterChain) { ... if ($request->getCookie($this->getParameter('cookie_name'))) ... } }
Condition参数被过滤器链测试来决定是否必须被执行。因此自定义过滤器声明能够依赖一个应用配置。要是过滤器执行,记得在应用的app.yml中加入:
all: enable_remember_me: on
过滤器示例
如果想在项目中包含特定的代码,你可以通过过滤器实现(layout方式需要在每一个应用中都要设置),看下面的代码:
class sfGoogleAnalyticsFilter extends sfFilter { public function execute($filterChain) { // 在动作之前什么也不做 $filterChain->execute(); // 使用下面的代码修饰响应 $googleCode = ' <script src="https://www.google-analytics.com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct="UA-'.$this->getParameter('google_id').'";urchinTracker(); </script>'; $response = $this->getContext()->getResponse(); $response->setContent(str_ireplace('</body>', $googleCode.'</body>',$response->getContent())); } }
这不是一种好的方式,因为在非HTML响应中不适用,只是一个例子而已。
下个例子是转换http请求到https请求
class sfSecureFilter extends sfFilter { public function execute($filterChain) { $context = $this->getContext(); $request = $context->getRequest(); if (!$request->isSecure()) { $secure_url = str_replace('http', 'https', $request->getUri()); return $context->getController()->redirect($secure_url); // We don't continue the filter chain } else { // The request is already secure, so we can continue $filterChain->execute(); } } }
过滤器广泛地应用于插件,允许全面地扩展应用的特性。
模块配置
一些模块行为依赖配置,要修改他们必须在模块的config目录下建立module.yml并为每一个环境(或者all)定义设置。
看个例子:apps/myapp/modules/mymodule/config/module.yml
all: #对所有环境 enabled: true is_internal: false view_name: sfPHP
Enable参数允许你在模块中禁用所有动作,这样所有动作都将专项到module_disabled_module/module_disabled_action动作(定义在settings.yml)
Is_internal参数定义动作只能内部调用,比如发送邮件只能有另一个动作调用而不是外部的直接调用。
View_name参数定义了view类,类必须继承自sfView。覆盖他后你将可以使用具有其他模板引擎其他的view系统,比如smarty。