Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Zend Framework 2应用程序中返回XML响应的正确方法是什么?_Xml_Api_Rest_Zend Framework2 - Fatal编程技术网

在Zend Framework 2应用程序中返回XML响应的正确方法是什么?

在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');

我正在开发一个小型的ZF2应用程序,它为客户端提供一些API端点。它通过JSON返回一些简单的数据

它有一个
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示例:-希望这有帮助。