Joomla - 返回JSON数据的Controller任务

时间:2013-05-24 16:40:14

标签: php json joomla joomla2.5

我的控制器中有run任务。我希望它返回JSON数据。就目前而言,我将我的JSON数据包装在模板HTML中。如何告诉Joomla只从控制器返回JSON数据?这是我的功能:

public function run  ( ) {

    JFactory::getDocument()->setMimeEncoding( 'application/json' );

    JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');

    JRequest::setVar('tmpl','component');

    $data = array(
        'foo' => 'bar'
    );

    echo json_encode( $data );

}

然后返回:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en-gb" dir="ltr">
...
</head>
<body class="contentpane">

<div id="system-message-container">
</div>
    {"foo":"bar"}
</body>
</html>

我想得到:

{"foo":"bar"}

7 个答案:

答案 0 :(得分:16)

您无需构建特殊的JSON视图(view.json.php;或控制器progressreports.json.php)来实现这一目标。您唯一要做的就是回显JSON字符串并关闭应用程序。

public function run( )
{
    JFactory::getDocument()->setMimeEncoding( 'application/json' );
    JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');

    $data = array(
        'foo' => 'bar'
    );
    echo json_encode( $data );
    JFactory::getApplication()->close(); // or jexit();
}

如果要提供带有HTML和JSON输出的相同函数(由调用者选择),则只需要一个单独的视图(或控制器)。

答案 1 :(得分:2)

得到了答案。

我需要制作一个新的控制器。在我的情况下调用了原始控制器,progressreports.php - 我创建了一个名为progressreports.raw.php的新控制器。

然后在调用url时,添加format = raw。即。

index.php?option=com_foo&task=progressreports.run&format=raw

答案 2 :(得分:2)

您需要使用jexit()返回没有任何Joomla输出的json数据。

public function run  ( ) {

    $data = array(
        'foo' => 'bar'
    );

    echo json_encode( $data );
    jexit();

}

答案 3 :(得分:1)

根据你正在做的事情,你可能想制作一个json文档,whatever.json.php而不是whatever.html.php。

答案 4 :(得分:1)

我检查了接受的答案,它与joomla 3.4.3不兼容。如果有人有同样的问题,这里是低joomla版本的解决方案:

$data = array(
    'foo' => 'bar'
);
header('content-type: application/json; charset=utf-8');
echo json_encode($data);
JFactory::getApplication()->close();

仅当您要提供要下载的文件时才需要内容处置标题。

关: 我只是想结束这个项目并喝一些想忘了它。即使从头开始并编写新的CMS也不会那么痛苦。 :S

答案 5 :(得分:0)

我不喜欢JResponseJson,也喜欢为下一个请求排队消息,所以我在组件的主控制器上创建了以下方法:

public function returnJson($data)
{
    $app = Factory::getApplication();

    // Persist messages if they exist. (Same as CMSApplication->redirect)
    $session = \JFactory::getSession();
    $session->set('application.queue', $app->getMessageQueue());

    // Send json mime type.
    $app->mimeType = 'application/json';
    $app->setHeader('Content-Type', $app->mimeType . '; charset=' . $app->charSet);
    $app->sendHeaders();

    echo json_encode($data);

    $app->close();
}

在控制器或子控制器的任何任务中,您现在可以执行以下操作:

public function sampleTask()
{
    $app = Factory::getApplication();
    $app->enqueueMessage("Done (for the next user's request)", 'success');
    $this->returnJson("json data");
}

答案 6 :(得分:0)

Joomla 4

您必须将参数 &format=json 添加到您的 URL。 这告诉系统您正在等待 json 响应。系统将呈现 JsonDocument 并发送正确的浏览器标头作为响应。

index.php?option=com_foo&task=report.run&format=json
class Report extends BaseController {

   public function run() {
       $data = [
         'foo' => 'bar'
       ];

       $response = new ResponseJson($data);

       echo $response;
   }
}

无需使用 $app->close(); 关闭应用程序,因为 Joomla 的架构会为您处理。

如果关闭应用程序,您将在渲染过程中遗漏很多东西。许多事件不会被触发。此外,您必须手动发送内容类型的标头。

您的代码应该如下所示。这种方法不推荐

class Report extends BaseController {

   public function run() {

       $this->app->mimeType = 'application/json';
       $this->app->setHeader('Content-Type', $this->app->mimeType . '; charset=' . $this->app->charSet);
       $this->app->sendHeaders();

       $data = [
         'foo' => 'bar'
       ];

       $response = new ResponseJson($data);

       echo $response;

       $this->app->close();
   }
}