2010-05-13 36 views

Trả lời

82

Tạo chức năng này trong (cơ sở) điều khiển của bạn:

/** 
* 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(); 
} 

Sau đó, chỉ cần gọi vào cuối hành động của bạn:

$this->renderJSON($yourData); 
+0

Tôi đã nhận thấy rằng việc đặt tiêu đề **() ** hoặc ** Yii :: app() -> end(); ** không tạo ra bất kỳ sự khác biệt nào.Trong Công cụ nhà phát triển Chrome, nếu bạn nhận thấy ** Tiêu đề phản hồi ** trong tab ** Tiêu đề **, tất cả đều cung cấp cùng một Độ dài nội dung. Nếu ajax đã được thực hiện với đầu ra được mong đợi ở định dạng "json", thì ngay cả khi HTML được gửi đi, trình duyệt/jQuery xử lý đáp ứng đó là json. Và dường như nó hoạt động trong tất cả các trình duyệt hiện đại. Mặc dù, tôi không phủ nhận rằng việc đặt tiêu đề() là một điều tốt. – mohitp

+0

Thay vì tắt các tuyến nhật ký web, phương pháp này sẽ mạnh mẽ hơn (chưa được thử nghiệm): ~~~ ob_start(); Yii :: app() -> end (0, false); ob_end_clean(); thoát (0); – marcovtwout

9
$this->layout=false; 
header('Content-type: application/json'); 
echo json_encode($arr); 
Yii::app()->end(); 
+0

json_encode không hoạt động với các kiểu –

+4

Một vài tewaks: sử dụng CJSON :: encode() cho các mô hình; không cần phải làm '$ this-> layout = false' vì' Yii :: app() -> end() 'sẽ chấm dứt ứng dụng mà không xuất ra layout. – Ethan

+0

Tôi nghĩ tốt hơn là bạn nên thay đổi câu trả lời hay nhất cho @marcovtwout –

19
$this->layout=false; 
header('Content-type: application/json'); 
echo CJavaScript::jsonEncode($arr); 
Yii::app()->end(); 
+0

Cũng đừng quên vô hiệu hóa WebLogRoutes trước khi gọi Yii :: app() -> end() hoặc thông tin gỡ lỗi có thể được thêm vào json của bạn và có khả năng hiển thị nó không hợp lệ . – marcovtwout

+0

khá chắc chắn rằng kết thúc() tắt các bản ghi, đó là lý do tại sao tôi thêm nó ở đây –

+1

Nó không. end(): "Chấm dứt ứng dụng. Phương thức này thay thế hàm exit() của PHP bằng cách gọi onEndRequest trước khi thoát." Và trong CLogRouter (http://www.yiiframework.com/doc/api/1.1/CLogRouter#processLogs-detail): "Phương thức này là một trình xử lý sự kiện cho sự kiện CApplication :: onEndRequest." – marcovtwout

-1
Yii::app()->end() 

Tôi nghĩ rằng giải pháp này không phải là cách tốt nhất để kết thúc dòng chảy ứng dụng, vì nó sử dụng exit() chức năng của PHP, phù thủy có nghĩa là thoát ngay lập tức từ dòng chảy thực hiện. Có, có bộ xử lý onEndRequest của Yii và số register_shutdown_function của PHP nhưng nó vẫn quá tàn bạo.

Đối với tôi, cách tốt hơn là này

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; 
} 

Vì vậy, dòng chảy ứng dụng tiếp tục thực hiện ngay cả sau khi.

+0

Nếu bạn đã đặt layout = false, một 'return' đơn giản sẽ làm gì? Thậm chí có thể được bỏ qua. Tôi thấy không có lý do để thử/bắt và tạo ngoại lệ tùy chỉnh. – marcovtwout

+1

Điều đó thật tệ. Ném một ngoại lệ để xuất đáp ứng. – grantwparks

+0

Bây giờ, sau một thời gian, tôi hoàn toàn đồng ý rằng việc sử dụng các ngoại lệ để quản lý logic điều khiển/trình bày là sai. – Mihailoff

0

thêm một cách đơn giản bằng cách sử dụng

echo CJSON::encode($result); 

mã ví dụ:

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); 
     } 
} 

cổ vũ :)

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'); 
    } 

} 
0

Trong controller action mà bạn muốn làm cho JSON dữ liệu, ví dụ như: 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 
} 

Xem thêm Yii API

10

Đối Yii2 bên trong một bộ điều khiển :

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; 
} 
+2

Điều này đáng lẽ phải là câu trả lời được chấp nhận. 1 để theo dõi api của Yii. – Gogol

+0

Cảm ơn bạn!^- ^ –

Các vấn đề liên quan