【问题标题】:How to get response as json format(application/json) in yii?如何在 yii 中以 json 格式(应用程序/json)获得响应?
【发布时间】:2011-02-18 23:15:13
【问题描述】:

如何在 yii 中获取 json 格式的响应(application/json)?

【问题讨论】:

    标签: php yii


    【解决方案1】:

    对于 Yii 1:

    在你的(基础)控制器中创建这个函数:

    /**
     * Return data to browser as JSON and end application.
     * @param array $data
     */
    protected function renderJSON($data)
    {
        header('Content-type: application/json');
        echo CJSON::encode($data);
    
        foreach (Yii::app()->log->routes as $route) {
            if($route instanceof CWebLogRoute) {
                $route->enabled = false; // disable any weblogroutes
            }
        }
        Yii::app()->end();
    }
    

    然后只需在操作结束时调用:

    $this->renderJSON($yourData);
    

    对于 Yii 2:

    Yii 2 has this functionality built-in,在控制器操作的末尾使用以下代码:

    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return $data;
    

    【讨论】:

    • 我注意到设置 header()Yii::app()->end(); 没有任何区别。在 Chrome 开发者工具中,如果您注意到 Header 选项卡下的 Response Header,它们都会给出相同的 Content-Length。如果使用“json”格式的预期输出制作了 ajax,那么即使发送了 HTML,浏览器/jQuery 也会将该响应视为 json。它似乎适用于所有现代浏览器。不过,我不否认设置 header() 是一件好事。
    • 这种方法不会禁用网络日志路由,而是更健壮(尚未测试):~~~ ob_start(); Yii::app()->end(0, false); ob_end_clean();退出(0);
    【解决方案2】:
    $this->layout=false;
    header('Content-type: application/json');
    echo CJavaScript::jsonEncode($arr);
    Yii::app()->end(); 
    

    【讨论】:

    • 另外不要忘记在调用 Yii::app()->end() 之前禁用 WebLogRoutes,否则调试信息可能会附加到您的 json 中并可能使其无效。
    • 很确定 end() 会关闭日志,这就是我在这里添加它的原因
    • 它没有。 end(): "终止应用程序。此方法通过在退出前调用 onEndRequest 来替换 PHP 的 exit() 函数。"在 CLogRouter (yiiframework.com/doc/api/1.1/CLogRouter#processLogs-detail) 中:“此方法是 CApplication::onEndRequest 事件的事件处理程序。”
    • @marcovtwout,是的,你是对的。我在想 exit() 可以在 Yii 之前结束应用程序,因此没有日志。
    【解决方案3】:

    对于控制器内部的 Yii2:

    public function actionSomeAjax() {
        $returnData = ['someData' => 'I am data', 'someAnotherData' => 'I am another data'];
    
        $response = Yii::$app->response;
        $response->format = \yii\web\Response::FORMAT_JSON;
        $response->data = $returnData;
    
        return $response;
    }
    

    【讨论】:

    • 这应该是公认的答案。 +1 关注 Yii 的 api。
    • 谢谢先生! ^-^
    【解决方案4】:
    $this->layout=false;
    header('Content-type: application/json');
    echo json_encode($arr);
    Yii::app()->end(); 
    

    【讨论】:

    • 一些小技巧:对模型使用 CJSON::encode();无需执行$this->layout=false,因为Yii::app()->end() 将终止应用程序而不输出布局。
    • 我认为最好将最佳答案更改为@marcovtwout
    【解决方案5】:
    class JsonController extends CController {
    
        protected $jsonData;
    
        protected function beforeAction($action) {
            ob_clean(); // clear output buffer to avoid rendering anything else
            header('Content-type: application/json'); // set content type header as json
            return parent::beforeAction($action);
        }
    
        protected function afterAction($action) {
            parent::afterAction($action);
            exit(json_encode($this->jsonData)); // exit with rendering json data
        }
    
    }
    
    class ApiController extends JsonController {
    
        public function actionIndex() {
            $this->jsonData = array('test');
        }
    
    }
    

    【讨论】:

      【解决方案6】:

      使用更简单的方法

      echo CJSON::encode($result);
      

      示例代码:

      public function actionSearch(){
          if (Yii::app()->request->isAjaxRequest && isset($_POST['term'])) {
                  $models = Model::model()->searchNames($_POST['term']);
                  $result = array();
                  foreach($models as $m){
                      $result[] = array(
                              'name' => $m->name,
                              'id' => $m->id,
                      );
      
      
                  }
                  echo CJSON::encode($result);
              }
      }
      

      干杯:)

      【讨论】:

        【解决方案7】:

        在你要渲染JSON数据的控制器动作中,例如:actionJson()

        public function actionJson(){
            $this->layout=false;
            header('Content-type: application/json');
            echo CJSON::encode($data);
            Yii::app()->end(); // equal to die() or exit() function
        }
        

        查看更多Yii API

        【讨论】:

          【解决方案8】:

          对于 Yii2 使用这个简单易记的选项

          Yii::$app->response->format = "json";
          return $data
          

          【讨论】:

            【解决方案9】:
            Yii::app()->end()
            

            我认为这个解决方案不是结束应用程序流的最佳方式,因为它使用 PHP 的exit() 函数,巫婆意味着立即退出执行流。是的,有 Yii 的 onEndRequest 处理程序和 PHP 的 register_shutdown_function,但它仍然过于宿命。

            对我来说更好的方法是这个

            public function run($actionID) 
            {
                try
                {
                    return parent::run($actionID);
                }
                catch(FinishOutputException $e)
                {
                    return;
                }
            }
            
            public function actionHello()
            {
                $this->layout=false;
                header('Content-type: application/json');
                echo CJavaScript::jsonEncode($arr);
                throw new FinishOutputException;
            }
            

            因此,应用程序流甚至在之后继续执行。

            【讨论】:

            • 如果你已经把 layout=false,一个简单的'return'就行了?甚至可以省略。我认为没有理由尝试/捕获并创建自定义异常。
            • 那太糟糕了。抛出异常以输出响应。
            • 现在,一段时间后我完全同意使用异常来管理控制器/表示逻辑是错误的。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-02-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-03
            • 1970-01-01
            相关资源
            最近更新 更多