解惑
估计这块疑团是不少的,尤其是不看源码的同学,能够控制Yaf响应输出响应相关类就有Yaf/Dispatcher,Yaf/Controller_Abstract,另外两个类又分别有相应的属性用来控制响应输出,而属性又对应的类方法来设置。
Yaf/Dispatcher类属性
_auto_render
自动渲染功能开关,默认1。自动渲染是指根据当前请求的控制器Controller和动作Action自动寻找模块文件,加载与渲染模块,之后返回结果或者输出。
PHP代码设置:
1
2
3
4
Yaf/Dispatcher::getInstance()->autoRender($flag);
Yaf/Dispatcher::getInstance()->disableView();
Yaf/Dispatcher::getInstance()->enableView();
源码yaf_dispatcher.c,735-773行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
if (auto_render) {
ret = NULL;
if (!Z_BVAL_P(instantly_flush)) {
zend_call_method_with_1_params(&executor, ce, NULL, "render", &ret, action);
zval_ptr_dtor(&executor);
if (!ret) {
zval_ptr_dtor(&action);
return 0;
} else if (IS_BOOL == Z_TYPE_P(ret) && !Z_BVAL_P(ret)) {
zval_ptr_dtor(&ret);
zval_ptr_dtor(&action);
return 0;
}
if (Z_TYPE_P(ret) == IS_STRING && Z_STRLEN_P(ret)) {
yaf_response_alter_body(response, NULL, 0, Z_STRVAL_P(ret), Z_STRLEN_P(ret), YAF_RESPONSE_APPEND TSRMLS_CC);
}
zval_ptr_dtor(&ret);
} else {
zend_call_method_with_1_params(&executor, ce, NULL, "display", &ret, action);
zval_ptr_dtor(&executor);
if (!ret) {
zval_ptr_dtor(&action);
return 0;
}
if ((Z_TYPE_P(ret) == IS_BOOL && !Z_BVAL_P(ret))) {
zval_ptr_dtor(&ret);
zval_ptr_dtor(&action);
return 0;
}
zval_ptr_dtor(&ret);
}
} else {
zval_ptr_dtor(&executor);
}
_return_response
返回包含请求正文的响应对象开关,默认为0。默认情况下,Yaf的自动渲染查找并渲染模板(render,并非display),渲染结果写入Yaf/Response_Abstract实例的_body属性,在分发器结束分发之后,输出_body(数组遍历输出)属性的值,并清空_body。设置此属性为1,分发器结束分发之后,不会输出和清空_body,可以通过Yaf/Application的run(),Yaf/Dispather的dispatch(),或者Yaf/Controller_Abstract的getResponse()等方法返回响应对象。进而调用Yaf/Response_Abstract实例的getBody()方法获取响应正文。
PHP代码设置:
1
Yaf/Dispatcher::getInstance()->returnResponse($flag);
源码yaf_dispatcher.c,941-948行
1
2
3
4
5
6
return_response = zend_read_property(yaf_dispatcher_ce, dispatcher, ZEND_STRL(YAF_DISPATCHER_PROPERTY_NAME_RETURN), 1 TSRMLS_CC);
if (!Z_BVAL_P(return_response)) {
(void)yaf_response_send(response TSRMLS_CC);
yaf_response_clear_body(response, NULL, 0 TSRMLS_CC);
}
_instantly_flush
立即输出响应正文开头,默认为0。默认情况下,Yaf自动渲染调用Yaf/Controller_Abstract的render方法,渲染模板,当此属性设置为1时,Yaf调用Yaf/Contrller_Abstract的display方法,直接渲染并输出,但不设置Yaf/Response_Abstract实例的_body属性。
PHP代码设置:
1
Yaf/Dispatcher::getInstance()->flushInstantly($flag);
注意:_auto_render设置为0时,_return_response和_instantly_flush的设置将无效。
Yaf/Controller_Abstract类属性
yafAutoRender
自动渲染功能开头,默认null。此属性的作用与Yaf/Dispather类的_auto_render作用相同,但是优先级更高。
PHP代码设置:
1
$this->yafAutoRender = true;
其中$this代表实现Yaf/Controller_Abstract的控制器类的当前实例。
Yaf响应输出响应相关的方法
1
Yaf/Controller_Abstract::display($template_file);
渲染模板并输出结果
1
Yaf/Controller_Abstract::render($template_file);
渲染模板,并返回结果
1
Yaf/Response_Abstract::setBody($content, $type);
设置响应正文内容为$content,类型为$type;也即设置Yaf/Response_Abstract的_body属性键为$type对应的值为$content。注意如果已经存在则为追加模式。
1
Yaf/Response_Abstract::getBody($type = 'content');
获取$type对应的响应正文
1
Yaf/Response_Abstract::response();
输出所有类型的响应正文
1
Yaf/Response_Abstract::clearBody($type);
清空全部或者$type类型的响应正文