Phalcon是否支持开箱即用的内容协商,还是有一些易于实施的解决方案?我正在搜寻网,却没有看到它。
谢谢!
答案 0 :(得分:1)
简短的回答是否定的,感谢上帝,或者我们还有100个非主要组件的错误:)
您可以轻松地将现有的库(例如Negotiation)插入到DI中,然后在整个应用程序中全局使用它。
$di->setShared('negotiator', function(){
return new \Negotiation\Negotiator();
});
$bestHeader = $di->getShared('negotiator')->getBest('en; q=0.1, fr; q=0.4, fu; q=0.9, de; q=0.2');
请记住,使用示例中的默认服务器配置(.htaccess / Nginx),静态文件将按原样提供,而不会被Phalcon拦截。因此,对于来自服务器的服务器文件,最好创建一个单独的控制器/操作来处理它,而不是让所有请求都通过你的应用程序。
修改强>
如果只是根据常见的区别(标题,参数,方法)启用您的应用程序发送xml或json,那么您可以轻松地在没有外部框架的情况下完成它。有许多策略,最简单的方法是拦截Dispatcher::dispatch()
,决定返回哪些内容并相应地配置视图和响应 - Phalcon将完成其余的工作。
/**
* All controllers must extend the base class and actions must set result to `$this->responseContent` property,
* that value will be later converted to the appropriate form.
*/
abstract class AbstractController extends \Phalcon\Mvc\Controller
{
/**
* Response content in a common format that can be converted to either json or xml.
*
* @var array
*/
public $responseContent;
}
/**
* New dispatcher checks if the last dispatched controller has `$responseContent` property it will convert it
* to the right format, disable the view and direcly return the result.
*/
class Dispatcher extends \Phalcon\Mvc\Dispatcher
{
/**
* @inheritdoc
*/
public function dispatch()
{
$result = parent::dispatch();
$headerAccept = $this->request->getHeader('Accept');
$headerContentType = $this->request->getHeader('Content-Type');
$lastController = $this->getLastController();
// If controller is an "alien" or the response content is not provided, just return the original result.
if (!$lastController instanceof AbstractController || !isset($lastController->responseContent)) {
return $result;
}
// Decide what content format has been requested and prepare the response.
if ($headerAccept === 'application/json' && $headerContentType === 'application/json') {
$response = json_encode($lastController->responseContent);
$contentType = 'application/json';
} else {
$response = your_xml_convertion_method_call($lastController->responseContent);
$contentType = 'application/xml';
}
// Disable the view – we are not rendering anything (unless you've already disabled it globally).
$view->disable();
// Prepare the actual response object.
$response = $lastController->response
->setContent($response)
->setContentType($contentType);
// The returned value must also be set explicitly.
$this->setReturnedValue($response);
return $result;
}
}
// In your configuration you must insert the right dispatcher into DI.
$di->setShared('dispatcher', function(){
return new \The\Above\Dispatcher();
});
只是想到你可以使用dispatch loop events实现同样的目标。理论上的解决方案可能看起来更优雅,但我从未尝试过,所以你可能想自己尝试一下。