在Zend Framework 2应用程序中返回XML响应的正确方法是什么?
我正在开发一个小型的ZF2应用程序,它为客户端提供一些API端点。它通过JSON返回一些简单的数据 它有一个在Zend Framework 2应用程序中返回XML响应的正确方法是什么?,xml,api,rest,zend-framework2,Xml,Api,Rest,Zend Framework2,我正在开发一个小型的ZF2应用程序,它为客户端提供一些API端点。它通过JSON返回一些简单的数据 它有一个FooController扩展BaseRestController和AbstractRestfulController: FooController extends BaseRestController { // .... public function getList() { $data = array('foo' => 'bar');
FooController
扩展BaseRestController
和AbstractRestfulController
:
FooController extends BaseRestController
{
// ....
public function getList()
{
$data = array('foo' => 'bar');
return $this->send($data);
}
}
if ($format === 'json') {
return new JsonModel($data);
} else {
return new XmlModel($data);
}
以及:
现在我想根据用户的选择通过XML返回相同的数据。我想我必须在BaseRestController
中的send()
方法中执行类似的操作:
FooController extends BaseRestController
{
// ....
public function getList()
{
$data = array('foo' => 'bar');
return $this->send($data);
}
}
if ($format === 'json') {
return new JsonModel($data);
} else {
return new XmlModel($data);
}
我查看了内置的,它扩展了Zend\View\Model\ViewModel
,并添加了将变量序列化为JSON的serialize()
方法
我想我必须写一个类似的XmlModel,但我不知道如何正确地写这个模型,以及如何正确地告诉我的控制器这个新模型
需要哪些类别/工厂/渲染器/策略来实现这一点
我阅读了文档的一节,但所有现有的解决方案都会检查Accept HTTP标头,我不需要与标头交互,客户端只需在我的应用程序中将所需格式作为路由参数传递,如/rest/foo?format=json
或/rest/foo?format=xml
我还发现了bitbucket上的Netglue扩展,他们写了8个类,这听起来对我来说太过分了
真正的问题是,真的需要编写八个不同的类来转换和返回XML格式的结构化数据吗
应该还有其他选择,我想学习并理解实现这一点的正确方法是什么?查看Zend\View\Model\JsonModel中的JsonModel。创建ViewModel的类扩展。在序列化方法中,请使用以下代码
$test_array = array (
'bla' => 'blub',
'foo' => 'bar',
'another_array' => array (
'stack' => 'overflow',
),
);
$xml = new SimpleXMLElement('<root/>');
array_walk_recursive($test_array, array ($xml, 'addChild'));
print $xml->asXML();
$test\u数组=数组(
“bla”=>“blub”,
‘foo’=>‘bar’,
“另一个数组”=>数组(
'堆栈'=>'溢出',
),
);
$xml=新的SimpleXMLElement(“”);
数组_walk_recursive($test_数组,array($xml,'addChild'));
打印$xml->asXML();
如果您只想在一个操作中使用它,就不需要xmlModel。
只需将数据转换为正确的XML,然后:
$response = new \Zend\Http\Response();
$response->getHeaders()->addHeaderLine('Content-Type', 'text/xml; charset=utf-8');
$response->setContent($xml);
return $response;
@alex bernatskyi发现了一个非常好的解决方案,如果您只需要一种方法:
public function init()
{
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('xml', 'xml')->initContext('xml');
}
由于zf 2.0.4可以处理内容协商 见公共关系:
class SomeController扩展了AbstractActionController
{
受保护的$acceptCriteria=数组(
'Zend\View\Model\JsonModel'=>数组(
'应用程序/json',
),
'Zend\View\Model\FeedModel'=>数组(
“应用程序/rss+xml”,
),
);
公共职能行动()
{
$model=$this->acceptableViewModelSelector($this->acceptCriteria);
//可能会根据返回的模型改变执行
if($JsonModel的模型实例){
// ...
}
}
}
Xml唯一的标记,难道不能返回一个常规视图模型,在模板中使用Xml,而不使用布局吗?是的,json也是。但是内容类型如何:application/json;charset=utf-8
由AbstractRestfulController添加的标题?我还应该在控制器级别手动创建
零件吗?我还想了解这个render()
方法存在的原因:我添加了@Exlord的示例,并在这里包含了一个XMLWriter示例:-希望这有帮助。