class mymoduleActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
// Retrieving request parameters
$password = $request->getParameter('password');
// Retrieving controller information
$moduleName = $this->getModuleName();
$actionName = $this->getActionName();
// Retrieving framework core objects
$userSession = $this->getUser();
$response = $this->getResponse();
$controller = $this->getController();
$context = $this->getContext();
// Setting action variables to pass information to the template
$this->setVar('foo', 'bar');
$this->foo = 'bar'; // Shorter version
}
}
sfController: 控制器对象(->getController())
sfRequest: 请求对象 (->getRequest())
sfResponse: 应答对象 (->getResponse())
sfUser: 用户 session 对象 (->getUser())
sfRouting:路由对象(->getRouting())
sfMailer:邮件对象(->getMailer())
sfI18N:国际化对象 (->getI18N())
sfLogger: 日志对象 (->getLogger())
sfDatabaseConnection: 数据库链接对象 (- >getDatabaseConnection())
正常一般action的結尾 應該為
return sfView::SUCCESS;
如果有錯 應該這樣結尾
return sfView::ERROR;
symfony 就会去寻找 actionNameError.php 模板。
如果你想用一个特别的视图,你可以这样结尾:
return 'MyResult';
如果根本就没有或不需要视图—例如,批处理文件的执行–应该这样结尾:
return sfView::NONE;
用 sfView::NONE 越过视图层直接输出回应
public function executeIndex()
{
$this->getResponse()->setContent("<html><body>Hello, World!</body></html>");
return sfView::NONE;
}
// Is equivalent to
public function executeIndex()
{
return $this->renderText("<html><body>Hello, World!</body></html>");
}
例 6-10 – 避开视图层,但应答有 HTTP 头
public function executeRefresh()
{
$output = '<"title","My basic letter"],["name","Mr Brown">';
$this->getResponse()->setHttpHeader("X-JSON", '('.$output.')');
return sfView::HEADER_ONLY;
}
如果动作需要一个特殊的模板,去掉 return 声明, 用 setTemplate()方法。
$this->setTemplate('myCustomTemplate');
public function executeIndex()
{
$this->setTemplate('myCustomTemplate');
}
From action to action
跳到另一个动作
在一些情况下,一个动作结束时需要执行另一个动作。例如,一个处理表单提交的动作在更新数据库后通常被跳转到另一个动作上。动作类里提供了两个方法可以执行另一个动作:
- 如果动作转发给另一个动作:
- 如果跳转到另一个动作:
$this->forward('otherModule', 'index');
$this->redirect('otherModule/index');
$this->redirect('http://www.google.com/');
NOTE forward 与 redirect 之后的动作代码不会被执行。这一点上与 return 语句是一样的。它们会抛出一个 sfStopException 异常来停止动作的执行; 这个异常稍后会被 symfony 截获然后忽略
如果一个表单通过 method="post"调用动作,你应该使用跳转。最大的优点是, 如果用户刷新页面,表单不会被重新提交;另外,如果用户点击后退键,浏览器会再显示表单,而不是询问用户是否要重新提交表单。
所以 sfActions 类有几个方法叫 forwardIf(), forwardUnless(), forward404If(), forward404Unless(), redirectIf(),redirectUnless()。这 些方法接受一个参数并且对它进行判断,如果判断结果是 true,xxxIf() 方法
表格 6-1 - sfWebRequest 对象里的方法
名称 | 功能 | 输出例子 |
---|---|---|
请求信息 | ||
isMethod($method) | 是POST还是GET方法 | true或者false |
getMethod() | 请求方法名 | 'POST' |
getHttpHeader('Server') | HTTP头值 | 'Apache/2.0.59 (Unix) DAV/2 PHP/5.1.6' |
getCookie('foo') | 称作foo人cookie的值 | 'bar' |
isXmlHttpRequest()* | 是否是Ajax访问 | true |
isSecure() | 是否是SSL访问 | true |
请求参数 | ||
hasParameter('foo') | 请求里是否包含foo | true或者false |
getParameter('foo') | Foo参数的值 | bar |
setParameterHolder()->getAll() | 所有参数数组 | array |
URI相关信息 | ||
getUri() | 完整的URI | 'http://localhost/frontend_dev.php/mymodule/myaction' |
getPathInfo() | 路径信息 | /mymodule/myaction' |
getReferer() | Referer(来源) | http://localhost/frontend_dev.php/ |
getHost() | 主机名 | 'localhost' |
getScriptName() | 前端控制器名 | 'frontend_dev.php' |
客户端浏览器信息 | ||
getLanguages() | 所有可接受的语言数组 | Array( [0] => fr [1] => fr_FR [2] => en_US [3] => en ) |
getCharsets() | 所有可接受的字符集数组 | Array( [0] => ISO-8859-1 [1] => UTF-8 [2] => * ) |
getAcceptableContentTypes() | 所有可接受的内容类型数组 | Array( [0] => text/xml [1] => text/html |
*只能用于prototype,Prototype,Mootools,和 jQuery库 | ||
** 有时会被代理服务器阻拦 |
短暂的属性
删除用户会话属性(如果不再需要这个属性了)是一个常见的问题。例如,在用户提交表单后,你想显示一个确认信息。 当处理表单的动作需要转发到另一个动作时,把信息从一个动作传到另一个动作唯一的办法就是把信息存在用户会话的属性里。在显示确认信息之后,你需要删除这 个属性。否则,这个属性就会 被存入会话里,一直到会话到期。你只需要定义短暂的属性,而不需要去删除。因为短暂的属性在接受到下一个请 求后会自动删除,使用户会话更清洁。在动作里,你可以这样来定义短暂的属性:
$this->getUser()->setFlash('notice', $value);
用户看到这一页后,发出一个新的请求并触发了下一个动作。在这第二个动作里, 你可以这样取得属性的值:
$value = $this->getFlash('attrib');
删除用户会话属性(如果不再需要这个属性了)是一个常见的问题。例如,在用户提交表单后,你想显示一个确认信息。 当处理表单的动作需要转发到另一个动作时,把信息从一个动作传到另一个动作唯一的办法就是把信息存在用户会话的属性里。在显示确认信息之后,你需要删除这 个属性。否则,这个属性就会 被存入会话里,一直到会话到期。
你只需要定义短暂的属性,而不需要去删除。因为短暂的属性在接受到下一个请 求后会自动删除,使用户会话更清洁。在动作里,你可以这样来定义短暂的属性:
$this->getUser()->setFlash('notice', $value);
用户看到这一页后,发出一个新的请求并触发了下一个动作。在这第二个动作里, 你可以这样取得属性的值:
$value = $this->getFlash('attrib');
会话管理
smfony 把ID 存在客户端的 cookies 上。symfony 的会话 cookies 就叫 symfony,
你可以在factories.yml 設定名稱。
例 6-17 - 在 apps/frontend/config/factories.yml 里,改变会话的 Cookie 名称
all:
storage:
class: sfSessionStorage
param:
session_name: my_cookie_name
访问限制
例 6-20 - 设置访问限制, 在 apps/frontend/modules/mymodule/config/security.yml 里
read:
is_secure: false # All users can request the read action
update:
is_secure: true # The update action is only for authenticated users
delete:
is_secure: true # Only for authenticated users
credentials: admin # With the admin credential
all:
is_secure: false # false is the default value anyway
is_secure: false # All users can request the read action
update:
is_secure: true # The update action is only for authenticated users
delete:
is_secure: true # Only for authenticated users
credentials: admin # With the admin credential
all:
is_secure: false # false is the default value anyway
访问授权
如果要调用设有权限的动作,用户必须被认证后并有相应的证书。你可以用sfUser 对象扩展用户的权限。 setAuthenticated()方法可以改变用户的认证状态,isAuthenticated()方法可以检查用户的认证状态。 例 6-22 是一个用户认证的简单例子。例 6-22 – 设置用户的认证状态
class myAccountActions extends sfActions
{
public function executeLogin($request)
{
if ($request->getParameter('login') === 'foobar')
{
$this->getUser()->setAuthenticated(true);
}
}
public function executeLogout()
{
$this->getUser()->setAuthenticated(false);
}
}
過濾器 filter還沒看