Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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
Cakephp3:如何返回json数据?_Json_Cakephp - Fatal编程技术网

Cakephp3:如何返回json数据?

Cakephp3:如何返回json数据?,json,cakephp,Json,Cakephp,我正在对cakePhp控制器进行ajax post调用: $.ajax({ type: "POST", url: 'locations/add', data: { abbreviation: $(jqInputs[0]).val(), description: $(jqInputs[1]).val()

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

$.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');
                    }
                }
            });
当我尝试此操作时,会收到以下错误消息:

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

在AppController中,我有这个

$this->loadComponent('RequestHandler');
启用

控制器功能如下所示:

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']);
            return json_encode(array('result' => 'success'));
        } else {
            //$this->Flash->error(__('The location could not be saved. Please, try again.'));
            return json_encode(array('result' => 'error'));
        }
    }
    $this->set(compact('location'));
    $this->set('_serialize', ['location']);
}

我错过了什么?是否需要其他设置?

不要返回json_编码结果,而是使用该结果设置响应正文并返回

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) 由于CakePHP3.4,我们应该使用

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

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

返回的东西很少
JSON
响应:

  • 加载
    RequestHandler
    组件
  • 将渲染模式设置为
    json
  • 设置内容类型
  • 设置所需数据
  • 定义
    \u序列化
  • 例如,您可以将前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)
    ;我不确定在
    GET
    请求的情况下是否返回
    json
    ,因此
    setJsonResponse
    方法在
    if post
    块中调用

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

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

    返回JSON数据时,需要定义数据类型和响应主体信息,如下所示:

    $cardInformation = json_encode($cardData);
    $this->response->type('json');
    $this->response->body($cardInformation);
    return $this->response;
    
    在您的情况下,只需更改此
    返回json_encode(数组('result'=>'success')带有以下代码的行:

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

    发送json不需要RequestHandler。 在控制员的行动中:

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

    在最新版本的CakePHP中,
    $this->response->type()
    $this->response->body()
    不推荐使用

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

    例如:

    (这是从公认的答案中删去的)


    我在这里看到的大多数答案要么是过时的,充斥着不必要的信息,要么是依赖于
    withBody()
    ,这让人觉得是权宜之计,而不是死板的方法

    以下是对我有效的方法:

    $my_results = ['foo'=>'bar'];
    
    $this->set([
        'my_response' => $my_results,
        '_serialize' => 'my_response',
    ]);
    $this->RequestHandler->renderAs($this, 'json');
    
    。似乎它不会很快被弃用

    更新:CakePHP 4

    $this->set(['my_response' => $my_results]);
    $this->viewBuilder()->setOption('serialize', true);
    $this->RequestHandler->renderAs($this, 'json');
    

    从cakePHP 4.x.x开始,假设您的控制器和路由设置如下所示,则以下各项应起作用: 控制器:/src/controller/studentscocontroller.php

    路由:/config/Routes.php


    虽然我不是CakePHP大师,但我使用的是cake>4,我需要通过ajax调用获得一些结果。为此,我在控制器上写下

    echo json_编码(Dashboard::recentDealers());死亡

    在我的JS文件中,我只需要使用

    JSON.parse(数据)

    ajax调用类似于

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

    控制器操作只能返回Cake\Network\Response或null。
    此错误消息有什么不清楚的地方?显然,您返回了一个字符串
    return json\u encode()
    。对不起,我还是不明白重点是什么?我返回一个数组,就像上面的例子一样?你没有。你读过这个吗?首先,不要返回json,只需回显它,以便在结果中打印它。第二,如果您没有将标题内容类型设置为json,那么您必须在ajax中提及它,如以下数据类型:'json'@AmanRawat No,您不会回显来自控制器操作的数据!您可以返回响应对象、在模板中回显数据,或者使用序列化视图;和$this->response->body($resultJ);帮了我很多,谢谢!我更新了anwser以包含验证错误。值得注意的是,由于CakePHP3.4,这不再有效。您应该改为使用
    return$this->response->withType(“application/json”)->withStringBody(json_encode($result))允许将字符串传递给不可变响应。这是一个方便的答案!另外,
    my_response
    可以是任何有效的键名,只需要在两个位置匹配即可。此外,这在CakePHP 3.6.10上起到了作用(我想我应该澄清一下),如果没有该组件,它将无法工作!所以这不是一个通用的解决方案。@MSS什么组件?RequestHandler组件被整理好了
    public function index()
        {
            $students = $this->Students->find('all');
            $this->set(compact('students'));
            $this->viewBuilder()->setOption('serialize',['students']);
        }
    
    <?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();
    });
    
     $.get('/recent-dealers', function (data, status) {
       console.log (JSON.parse(data)); });
    });