Can anyone tell me if there is a resolution to saving PHP classes with private members to MongoDb? I keep getting the following error
zero-length keys are not allowed, did you use $ with double quotes?'
I see there at least two existing question pertaining to the same question with no real answers.
Question 1
Question 2
all of my persistence classes have a private member that I need available but I’m not interested in creating a function to avoid the necessity for the private member since this is an instance based class that has multiple function utilizing the private member.
Web server Apache/2.2.22
PHP version PHP 5.4.6
PHP extension mongo/1.2.6
This would be a sample implementation, please don’t critique the code itself it is just to illustrate the type of behavior which is the Save of $this and the $private member in the base type:
<?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);
}
}
?>
The problem, as you know from Google Groups, is that the PHP driver actually omits private and protected variables from save. This is a fundamental problem within the core of the driver itself so there is no easy way around it. As you also know Derick created a JIRA for this: https://jira.mongodb.org/browse/PHP-624
@harald does actually state the way around, to create your own _to_array() and feed that into the save function, unfortunately this derives a fundamental problem again with how you have built your classes. You must use reflection for this like so:
And then use
$docwithin the save.You can however change your programming a bit to avoid the reflection (or just cache the result of the reflection to save the resource hog) by making a pre-defined array of
$schemawhich will house all the fields you wish to save. When you wish to add new fields on-demand you can just make your__setand__getupdate the in memory schema array. This way you can avoid the reflection altogether and just go for grabbing the schema array and it’s values.This is the method a lot of frameworks use to get around the problem, including Lithium, Yii, Kohona, CakePHP and more.