LoginSignup
4
5

More than 5 years have passed since last update.

cakephp3でjson(p)出力

Last updated at Posted at 2017-07-25

やっと重い腰をあげて2から3に移行する決意を固めました。そろそろ頃合いであろうと。
2を手足のように使って死ぬほど駄ウェブサービスを作っていた身としては、3でも変わらず駄ウェブサービスを世に送り続けたて煙たがられたいと思っておる次第であります(敬礼&失神)。

RequestHandlerComponentでリクエストを判別してデータビューを出力する方法

// src/WorksController.php

class WorksController extends AppController
{

    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('RequestHandler');
    }


    public function o()
    {

        $data = ['kikuko' => ['age' => 17]];
        $this->set([
            'data' => $data,
            '_serialize' => ['data'],
            '_jsonp' => TRUE // json出力の場合はいらないです
        ]);

    }

}

jsonの場合

すいません、jQuery使わせてください。

$.ajax('/works/o',
      {
        type: 'get',
        dataType: 'json'
      }
    )
    .done(function(data) {
      console.log(data.data.kikuko);
    })
    .fail(function() {
      console.log('error');
    });

dataTypeに'json'を指定すると、リクエストヘッダのAcceptが

Accept: application/json

になり、こいつをRequestHandlerComponentが認識してjsonでビューを出力してくれます。
なので、ただ http://localhost/works/o をたたいても Missing Template と言われてしまいます。

jsonpの場合

dataTypeに'jsonp'を指定すると、リクエストヘッダのAcceptが

Accept: text/javascript

になってしまい、RequestHandlerComponentがjsonでビューを出力してくれなくなってしまいます。
この場合は、拡張子 .json をルーティング時に渡すことで、jsonでビューを出力してもらいます。

// config/route.php

Router::extensions(['json', 'xml']);

特定のパスにだけ適用することもできるみたいです。
https://book.cakephp.org/3.0/ja/development/routing.html#file-extensions

これで、

$.ajax('/works/o.json',
      {
        type: 'get',
        dataType: 'jsonp'
      }
    )
    .done(function(data) {
      console.log(data.data.kikuko);
    })
    .fail(function() {
      console.log('error');
    });

とすることで、jsonpを受け取ることができます。違いは、

リクエスト先を

/works/o.json

にしたことと、dataTypeを'jsonp'にしたことですね。

リクエストを判別しないでjsonデータビューを出力する方法

もっと簡単にリクエストはどうあれ、jsonを出力できないんかという諸兄に。

// src/WorksController.php

class WorksController extends AppController
{

    public function o()
    {

        $data = ['kikuko' => ['age' => 17]];

        $this->viewBuilder()->className('Json');
        $this->set([
            'data' => $data,
            '_serialize' => ['data'],
            '_jsonp' => TRUE // json出力の場合はいらないです
        ]);

    }

}

viewBuilder に className('Json') を渡すことによって出力をjsonに限定できます。
これでどんなリクエストでも常にjsonで出力してくれます。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5