Yii JSON与关系

时间:2011-04-27 13:23:05

标签: json yii yii-relations

如何使用所有关系(和子对象关系?)返回对象。 现在我使用JsonBehavior但它只返回第一级关系,而不返回子相关对象。 我的源代码:

    $order = Order::model()->findByPk($_GET['id']);
    echo $order->toJSON();
    Yii::app()->end();

3 个答案:

答案 0 :(得分:3)

急切加载方法与主AR实例一起检索相关AR实例。这是通过将with()方法与AR中的find或findAll方法之一一起使用来实现的。例如,

$posts=Post::model()->with('author')->findAll();

上面的代码将返回一个Post实例数组。与惰性方法不同,每个Post实例中的author属性在访问属性之前已经填充了相关的User实例。热门加载方法不是为每个帖子执行连接查询,而是在一个连接查询中将所有帖子与作者一起带回来!

我们可以在with()方法中指定多个关系名称,并且急切加载方法将一次性全部恢复。例如,以下代码将带回帖子及其作者和类别:

$posts=Post::model()->with('author','categories')->findAll();

我们也可以进行嵌套的预先加载。我们将关系名称的层次表示传递给with()方法,而不是关系名称列表,如下所示,

$posts=Post::model()->with(
    'author.profile',
    'author.posts',
    'categories')->findAll();

以上示例将带回所有帖子及其作者和类别。它还将带回每位作者的个人资料和帖子。

也可以通过指定CDbCriteria :: with属性来执行预加载,如下所示:

$criteria=new CDbCriteria;
$criteria->with=array(
    'author.profile',
    'author.posts',
    'categories',
);
$posts=Post::model()->findAll($criteria);

$posts=Post::model()->findAll(array(
    'with'=>array(
        'author.profile',
        'author.posts',
        'categories',
    )
);

答案 1 :(得分:3)

我找到了解决方案。您可以使用$ row->属性来创建数据

    $magazines = Magazines::model()->with('articles')->findAll();


    $arr = array();
    $i = 0;
    foreach($magazines as $mag)
    {   
        $arr[$i] = $mag->attributes;
        $arr[$i]['articles']=array();
        $j=0;
        foreach($mag->articles as $article){
            $arr[$i]['articles'][$j]=$article->attributes;
            $j++;
        }
        $i++;
    }
    print CJSON::encode(array(
            'code' => 1001,
            'magazines' => $arr,
        ));

答案 2 :(得分:0)

这是经过长时间搜索才能满足此要求的最佳代码。 这将像魅力一样工作。

 protected function renderJson($o) {
    //header('Content-type: application/json');
    // if it's an array, call getAttributesDeep for each record
    if (is_array($o)) {
        $data = array();
        foreach ($o as $record) {
            array_push($data, $this->getAttributes($record));
        }
        echo CJSON::encode($data);
    } else {
        // otherwise just do it on the passed-in object
        echo CJSON::encode($this->getAttributes($o));
    }

    // this just prevents any other Yii code from being output
    foreach (Yii::app()->log->routes as $route) {
        if ($route instanceof CWebLogRoute) {
            $route->enabled = false; // disable any weblogroutes
        }
    }
    Yii::app()->end();
}

protected function getAttributes($o) {
    // get the attributes and relations
    $data = $o->attributes;
    $relations = $o->relations();
    foreach (array_keys($relations) as $r) {
        // for each relation, if it has the data and it isn't nul/
        if ($o->hasRelated($r) && $o->getRelated($r) != null) {
            // add this to the attributes structure, recursively calling
            // this function to get any of the child's relations
            $data[$r] = $this->getAttributes($o->getRelated($r));
        }
    }
    return $data;
}