Cakephp3:如何返回json数据?

时间:2016-12-08 14:43:36

标签: json cakephp

我正在对cakePhp控制器进行ajax调用:

public class postcontroller : basecontroller
{                      
        public ActionResult wall()
        {
            var client = new FacebookClient( Session['fb_access_token'] as string);
            var args = new Dictionary<string, object>();
            args["message"] = "Klaatu Verata N......(caugh, caugh)";

            try
            {
                client.Post("/me/feed", args); // post to users wall (feed)
                client.Post("/{page-id}/feed", args); // post to page feed
            }
            catch (Exception ex)
            {
                // Log if anything goes wrong 
            }

        }
}

当我尝试这个时,我收到以下错误消息:

  

控制器操作只能返回Cake \ Network \ Response或null。

在AppController中我有这个

$.ajax({
                type: "POST",
                url: 'locations/add',
                data: {
                  abbreviation: $(jqInputs[0]).val(),
                  description: $(jqInputs[1]).val()
                },
                success: function (response) {
                    if(response.status === "success") {
                        // do something with response.message or whatever other data on success
                        console.log('success');
                    } else if(response.status === "error") {
                        // do something with response.message or whatever other data on error
                        console.log('error');
                    }
                }
            });

启用。

Controller函数如下所示:

$this->loadComponent('RequestHandler');

我在这里想念什么?是否需要其他设置?

8 个答案:

答案 0 :(得分:16)

不是返回json_encode结果,而是使用该结果设置响应体并将其返回。

public function add()
{
    $this->autoRender = false; // avoid to render view

    $location = $this->Locations->newEntity();
    if ($this->request->is('post')) {
        $location = $this->Locations->patchEntity($location, $this->request->data);
        if ($this->Locations->save($location)) {
            //$this->Flash->success(__('The location has been saved.'));
            //return $this->redirect(['action' => 'index']);
            $resultJ = json_encode(array('result' => 'success'));
            $this->response->type('json');
            $this->response->body($resultJ);
            return $this->response;
        } else {
            //$this->Flash->error(__('The location could not be saved. Please, try again.'));
            $resultJ = json_encode(array('result' => 'error', 'errors' => $location->errors()));

            $this->response->type('json');
            $this->response->body($resultJ);
            return $this->response;
        }
    }
    $this->set(compact('location'));
    $this->set('_serialize', ['location']);
}

编辑(归功于@Warren Sergent)

自CakePHP 3.4起,我们应该使用

return $this->response->withType("application/json")->withStringBody(json_encode($result));

而不是:

$this->response->type('json');
$this->response->body($resultJ);
return $this->response;

CakePHP Documentation

答案 1 :(得分:9)

我在这里看到的大多数答案都是过时的,充满不必要的信息,或者依赖于withBody(),这感觉像是变通解决方案,而不是CakePHP方式。

以下是对我有用的:

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

$this->set([
    'my_response' => $my_results,
    '_serialize' => 'my_response',
]);
$this->RequestHandler->renderAs($this, 'json');

More info on RequestHandler。看来它不会很快被弃用。

答案 2 :(得分:6)

回复JSON的回复很少:

  1. 加载RequestHandler组件
  2. 将渲染模式设置为json
  3. 设置内容类型
  4. 设置所需数据
  5. 定义_serialize
  6. 例如,您可以将前3个步骤移动到父控制器类中的某个方法:

    protected function setJsonResponse(){
        $this->loadComponent('RequestHandler');
        $this->RequestHandler->renderAs($this, 'json');
        $this->response->type('application/json');
    }
    
    稍后在您的控制器中,您应该调用该方法,并设置所需的数据;

    if ($this->request->is('post')) {
        $location = $this->Locations->patchEntity($location, $this->request->data);
    
        $success = $this->Locations->save($location);
    
        $result = [ 'result' => $success ? 'success' : 'error' ];
    
        $this->setJsonResponse();
        $this->set(['result' => $result, '_serialize' => 'result']);
    }
    

    看起来你也应该检查request->is('ajax);我不确定在json请求的情况下返回GET,因此在setJsonResponse块内调用if-post方法;

    在您的ajax-call成功处理程序中,您应该检查result字段值:

    success: function (response) {
                 if(response.result == "success") {
                     console.log('success');
                 } 
                 else if(response.result === "error") {
                        console.log('error');
                 }
             }
    

答案 3 :(得分:1)

在最新版本的CakePHP中,已弃用$this->response->type()$this->response->body()

您应该使用$this->response->withType()$this->response->withStringBody()

例如:

这是从接受的答案中捏出来的

if ($this->request->is('post')) {
    $location = $this->Locations->patchEntity($location, $this->request->data);
    if ($this->Locations->save($location)) {
        //$this->Flash->success(__('The location has been saved.'));
        //return $this->redirect(['action' => 'index']);
        $resultJ = json_encode(array('result' => 'success'));

        $this->response = $this->response
            ->withType('application/json') // Here
            ->withStringBody($resultJ)     // and here

        return $this->response;
    }
}

Relevant Documentation

答案 4 :(得分:0)

当您返回JSON数据时,您需要定义数据类型和响应正文信息,如下所示:

$cardInformation = json_encode($cardData);
$this->response->type('json');
$this->response->body($cardInformation);
return $this->response;

在您的情况下,只需使用以下代码更改此return json_encode(array('result' => 'success'));行:

$responseResult = json_encode(array('result' => 'success'));
$this->response->type('json');
$this->response->body($responseResult);
return $this->response;

答案 5 :(得分:0)

RequestHandler不需要发送json。 在控制器的操作中:

$this->viewBuilder()->setClassName('Json');
$result = ['result' => $success ? 'success' : 'error'];
$this->set($result);
$this->set('_serialize', array_keys($result));

答案 6 :(得分:0)

从cakePHP 4.x.x开始,假设您的控制器和路由的设置如下所示,则以下各项应能正常工作: 控制器: /src/Controller/StudentsController.php

public function index()
    {
        $students = $this->Students->find('all');
        $this->set(compact('students'));
        $this->viewBuilder()->setOption('serialize',['students']);
    }

路由: <您的项目名称> /config/routes.php

<?php

use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;

/** @var \Cake\Routing\RouteBuilder $routes */
$routes->setRouteClass(DashedRoute::class);

$routes->scope('/', function (RouteBuilder $builder) {
 
    $builder->setExtensions(['json']);
    $builder->resources('Students');
    $builder->fallbacks();
});

运行 bin / cake服务器,并使用邮差/失眠或仅使用普通浏览器访问 http:// localhost:8765 / students.json 。 有关设置Restful controllersRestful Routing

的更多文档,请参见

不要忘记将邮递员和失眠的方法设置为 GET

答案 7 :(得分:0)

尽管我不是CakePHP专家,但我使用的是Cake> 4,所以我需要通过ajax调用获得一些结果。为此,我写了我的控制器,

echo json_encode(Dashboard :: recentDealers());死;

在我的JS文件中,我只需要使用来解析数据

JSON.parse(数据)

像这样的ajax调用

 $.get('/recent-dealers', function (data, status) {
   console.log (JSON.parse(data)); });
});