嵌入式文档数组YiiMongoDbSuite

时间:2013-09-03 10:57:04

标签: php mongodb yii yii-extensions

我有三节课。该课程包括各个阶段。这些阶段包括步骤。

class Course extends EMongoDocument{
....
    public function behaviors()
    {
        return array(
            'embeddedArrays' => array(
                'class'=>'ext.YiiMongoDbSuite.extra.EEmbeddedArraysBehavior',
                'arrayPropertyName'=>'stages',
                'arrayDocClassName'=>'Stage'
            ),
        );
    }
}

class Stage extends EMongoEmbeddedDocument{
...
    public function behaviors()
{
        return array(
            'embeddedArrays' => array(
                'class'=>'ext.YiiMongoDbSuite.extra.EEmbeddedArraysBehavior',
                'arrayPropertyName'=>'steps',
                'arrayDocClassName'=>'Step'
            ),
        );
}
class Step extends EMongoEmbeddedDocument{
...
}

在mongodb我有数据:

{
    "name" : "course1",
    "online" : "0",
    "author_id" : ObjectId("521df3f1e405688411000029"),
    "approved" : false,
    "stages" : [ 
        {
            "_id" : ObjectId("521dfd84e40568d80900002a"),
            "name" : null,
            "steps" : null,
            "price" : null
        }, 
        {
            "_id" : ObjectId("5220c648e40568701c000031"),
            "name" : null,
            "steps" : [ 
                {
                    "_id" : ObjectId("5220c648e40568701c000032"),
                    "name" : null
                }
            ],
            "price" : null
        }
    ],
    "short_description" : "test",
    "_id" : ObjectId("521dfd7ce40568d809000029")
}

当我尝试从mongodb读取数据时: 致命错误:在第104行的 * * extensions \ YiiMongoDbSuite \ extra \ EEmbeddedArraysBehavior.php中的非对象上调用成员函数toArray()

$arrayOfDocs[] = $doc->toArray();

如果舞台没有步骤,一切正常。我做错了什么?

2 个答案:

答案 0 :(得分:0)

GitHub上似乎有多个YiiMongoDbSuite版本。您使用的是canni/YiiMongoDbSuite的v1.3.6.3吗?

查看EEmbeddedArraysBehavior.php中的beforeToArray()方法,代码似乎访问该属性,然后立即对其进行迭代。如果文档中的stages.0.steps字段为null,我看不到行为代码中的第一个is_array()检查将如何通过。我建议调试函数并检查stages属性的值,将其保存到_cache属性的位置和foreach()迭代之前。我的猜测是它可能是一个包含单个元素的数组,其值为null

答案 1 :(得分:0)

我找到了解决方案。填充嵌入文档字段的值时,它会从嵌​​入文档的函数attributeNames()中获取一个数组(要填充的内容),然后翻转等等。因此,要修复NULL值,您应该填写该函数的返回数组。我的代码将帮助您:

<?php
class Pricing extends EMongoEmbeddedDocument {
    public $setup;
    public $monthly;
    public $annually;
    public function rules() {
        return array(
        );
    }
    public function attributeNames() {
        return array(
            'setup' => 'setup',
            'monthly' => 'monthly',
            'annually' => 'annually'
        );
    }
}

也是这段代码

public function setAttributes($values, $safeOnly=true)
    {
        if(!is_array($values))
            return;

        if($this->hasEmbeddedDocuments())
        {
            $attributes=array_flip($safeOnly ? $this->getSafeAttributeNames() : $this->attributeNames());

            foreach($this->embeddedDocuments() as $fieldName => $className)
                $this->$fieldName = new $className;
                if(isset($values[$fieldName]) && isset($attributes[$fieldName]))
                {
                    $this->$fieldName->setAttributes($values[$fieldName], $safeOnly);
                    unset($values[$fieldName]);
                }
        }

        parent::setAttributes($values, $safeOnly);
    }

帮助我防止致命错误致命错误:在EMongoDocument.php中的非对象上调用成员函数setAttributes()