Почему контроллер rest Yii2 дает ответ в формате XML?

В настоящее время я использую следующий код инициализации на моем модуле api

public function init()
{
    parent::init();
    Yii::$app->response->format = Response::FORMAT_JSON;
}

мой api возвращает ответ в формате XML в следующем примере.

public function actionTest()
{
    $items = ['one', 'two', 'three' => ['a', 'b', 'c']];
    return $items;
}

вот ответ:

<response>
  <item>one</item>
  <item>two</item>
   <three>
    <item>a</item>
    <item>b</item>
    <item>c</item>
   </three>
</response>

единственный способ заставить его работать-добавить эту строку к каждому поведению контроллера. я прочитал документацию, в которой говорится, что я могу инициализировать это в классе модуля, поэтому мне не нужно делать это в каждом контроллере. Я не знаю, почему он дает XML, хотя. и на всякий случай единственный способ-добавить его в мое поведение, мне нужно написать код для обработки имени, кода, состояния, типа, предыдущего и кода или Yii предоставляет YiirestController и yiirestActiveController, которые автоматически обрабатывают это. Очевидно, что они выводятся автоматически при возникновении ошибки.

{"name":"Not Found"
 "message":"Page not found.",
 "code":0,
 "status":404
 "type":"yiiwebNotFoundHttpException"
 "previous":{"name":"Invalid Route","message":"Unable to resolve the request: api/home/",
 "code":0,"type":"yiibaseInvalidRouteException"
 }
}

3 ответов


в приложениях Yii2 тип ответа по умолчанию-XML (и я думаю, что это по умолчанию для REST тоже). Во время HTTP-соединения обе стороны объявляют, какие данные могут отправлять и/или получать. Если эта информация не передается на сервер, тип данных по умолчанию-send (даже если вы указали, что это должен быть JSON в вашем приложении), чтобы гарантировать правильную связь. Если вы хотите получить данные JSON, вы должны добавить Accept: application/json заголовок к вашему запросу. И, вероятно, вам не нужно указывать его в php-коде, потому что Yii2 должен вычесть его из заголовков запросов.

вы можете найти больше объяснений, как это работает здесь.


после трех болезненных дней я нашел решения. Иногда довольно сложно объяснить эту проблему, когда вы исходите из целого мира JSON ExpressJS и NodeJS. Логически то, что делает Yii2, прекрасно, с другой стороны, 90% RESTful API ожидают, что вывод будет в JSON, поэтому вы явно не хотите устанавливать заголовки запросов каждый раз, когда вы делаете вызов API.

браузеры по умолчанию добавляют заголовки запросов как "Application / XML", следовательно, то, что вы видите на экране является XML вместо JSON.

переговорщик содержимого Yii2 при получении заголовков в виде application / xml форматирует ваш вывод в XML. Если вы сделаете тот же запрос, используя CURL или PostMan с заголовками, как "Application/JSON", вы получите желаемый результат.

Если вы хотите переопределить это поведение, просто добавьте функцию ниже в свой контроллер и включите следующее: -

использовать yii\web\Response; использовать yii\helpers\ArrayHelper;

public function behaviors()
  {
      return ArrayHelper::merge(parent::behaviors(), [
          [
              'class' => 'yii\filters\ContentNegotiator',
              'only' => ['view', 'index'],  // in a controller
              // if in a module, use the following IDs for user actions
              // 'only' => ['user/view', 'user/index']
              'formats' => [
                  'application/json' => Response::FORMAT_JSON,
              ],
              'languages' => [
                  'en',
                  'de',
              ],
          ],
      ]);
  }

Я тестирую ваш код, и он отлично работает

мой контроллер следующим образом :

<?php

namespace backend\controllers;


use yii\rest\Controller;
use yii;
use yii\web\Response;

class TestController extends Controller{

    public function init()
    {
        parent::init();
        Yii::$app->response->format = Response::FORMAT_JSON;
    }

    public function actionTest(){
        $items = ['one', 'two', 'three' => ['a', 'b', 'c']];
        return $items;
    }
}

выход :

{"0":"one","1":"two","three":["a","b","c"]}

проверьте пространство имен или отправьте код !