使用PHP驱动程序将具有私有成员的对象保存到MongoDb时出错

Rya*_*sch 2 php mongodb

谁能告诉我是否有解决方案将私有成员保存到MongoDb的PHP类?我一直收到以下错误

zero-length keys are not allowed, did you use $ with double quotes?'
Run Code Online (Sandbox Code Playgroud)

我看到至少有两个与同一个问题有关的问题没有真正的答案.
问题1 问题2

我的所有持久化类都有一个我需要的私有成员,但我对创建一个函数以避免私有成员的必要性感兴趣,因为这是一个基于实例的类,它具有利用私有成员的多个功能.

Web服务器Apache/2.2.22

PHP版本PHP 5.4.6

PHP扩展名mongo/1.2.6

这将是一个示例实现,请不要批评代码本身只是为了说明行为的类型,即$ this和基本类型中的$ private成员:

<?php

class PersistableObject extends AbstractBasePersistableObject
{
   public  $PublicSubTypeProperty;

    public function __construct()
    {
       parent::__construct();
    }

    public function GetDalConfigurationFromSubType()
    {
        //This object is just a wrapper DAL implemented based on
        //the php Mongo, MongoDb and MongoCollection objects
        return new MongoBasedDal();
    }
}


abstract class AbstractBasePersistableObject
{
   private $dalRef = null;
   public $PublicBaseProperty;

   public abstract function GetDalConfigurationFromSubType();

   public function __construct()
   {
      $this->dalRef = $this->GetDalConfigurationFromSubType();
   }

   public function Save()
   {
       $this->dalRef->Save($this);
   }
}

?>
Run Code Online (Sandbox Code Playgroud)

Sam*_*aye 5

谁能告诉我是否有解决方案将私有成员保存到MongoDb的PHP类?

正如您从Google网上论坛所知,问题是PHP驱动程序实际上忽略了保存中的私有和受保护变量.这是驱动程序核心内部的一个基本问题,因此没有简单的方法.您也知道Derick为此创建了一个JIRA:https://jira.mongodb.org/browse/PHP-624

@harald确实说明了方法,创建你自己的_to_array()并将其输入到save函数中,不幸的是,这再次导致了你如何构建类的根本问题.你必须像这样使用反射:

$reflect = new ReflectionClass(get_class($this));
$class_vars = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE);

foreach ($class_vars as $prop) {
    $doc[$prop->getName()] = $this->{$prop->getName()};
}
Run Code Online (Sandbox Code Playgroud)

然后$doc在保存中使用.

但是,您可以稍微改变您的编程以避免反射(或只是缓存反射的结果以保存资源占用),方法是使预定义的数组包含$schema您希望保存的所有字段.当您希望按需添加新字段时,您可以创建__set__get更新内存模式数组.这样你可以完全避免反射,只是去抓取模式数组及其值.

这是许多框架用来解决问题的方法,包括Lithium,Yii,Kohona,CakePHP等.