Currently, each document fetched from Mongo DB goes to a stdClass object. I would like to load this directly into my own custom class instead.
The class
class TestClass {
private $id;
private $class;
function __construct($id, $name) {
$this->id = $id;
$this->class = $class;
}
}
The code
$m = MongoDB\Driver\Manager('mongodb://<user>:<pass>@<host>/<db>');
$query = MongoDB\Driver\Query(['name' => 'TestFirst']);
// I tried adding the following line, but it says that the constructor args are missing.
// If I omit it, it just adds each cursor object as an instance of stdClass
$opt = ['cursor' => new TestClass];
$results = $m->executeQuery('newDb.testCollection', $query, $opt);
foreach ($results as $document) {
var_dump($document);
}
Is what I want to accomplish possible, or do I need to go through each stdClass object and cast it to an instance of TestClass?
The class itself needs to implement the MongoDB\BSON\Unserializable interface and the bsonUnserialize(array $data) method to convert an array from BSON data into the class in question.
class TestClass implements MongoDB\BSON\Unserializable, MongoDB\BSON\Serializable {
private $id;
private $name;
function __construct ($id, $name) {
$this->id = $id;
$this->name = $name;
}
function bsonUnserialize(array $data) {
// This will be called *instead* of the constructor if unserializing
$this->id = $data['_id'];
$this->id = $data['name'];
}
}
The type map of the MongoDB\Driver\Cursor that is returned from the query needs to be set to map a document to an instance of the custom class. The finished code looks like this.
$mongo = new MongoDB\Driver\Manager($constr);
$query = MongoDB\Driver\Query(['name' => 'TestFirst']);
$cursor = $mongo->executeQuery($query);
$cursor->setTypeMap('root' => 'array', 'document' => 'TestClass', 'array' => 'array');
foreach ($cursor as $doc) {
var_dump($doc);
}