MongoDB PHP Driver: Possibility of using custom MongoCursor?

101 views
Skip to first unread message

Blake Stovall

unread,
Feb 10, 2012, 12:24:58 AM2/10/12
to mongodb-dev
Would it be possible to add an option to a MongoCollection to allow
for the ability to pass in the class name of a class that extends
MongoCursor, so that it gets returned instead of the base MongoCursor?

I'd like to extend MongoCursor to override a couple of methods and add
some minor functionality. As it stands now, I have to create a wrapper
class and write one line methods to expose the individual MongoCursor
methods, like:

class ResultSet
{
/**
*
* @var MongoCursor
*/
protected $rs;

public function __construct( MongoCursor $rs )
{
$this->rs = $rs;
}

public function current()
{
return $rs->current();
}

public function valid()
{
return $this->rs->valid();
}

public function key()
{
return $this->rs->key();
}
}

Although this works, it would be much better for extensibility (not to
mention much cleaner) to be able to extend MongoCursor directly and
have MongoCollection return the new class instead. The other option
that I was just looking at is having a method in the MongoCursor class
that would take a MongoCursor and basically clone it into the current
object, but I'm not familiar with the underpinnings and how the C++
code works with the driver and at first glance that seems more
complicated.

Thanks,
Blake

Derick Rethans

unread,
Feb 10, 2012, 6:28:09 AM2/10/12
to mongo...@googlegroups.com

On Friday, February 10, 2012 5:24:58 AM UTC, Blake Stovall wrote:
Would it be possible to add an option to a MongoCollection to allow
for the ability to pass in the class name of a class that extends
MongoCursor, so that it gets returned instead of the base MongoCursor?

I think this will be quite tricky, as all over the driver we've MongoCursor
hard coded. Feel free to file a feature request in Jira though, and we'll
get to it at some point. I do agree this would be useful to have.

cheers,
Derick

Blake Stovall

unread,
Feb 12, 2012, 8:12:30 PM2/12/12
to mongodb-dev
Thanks for the response. I've never bothered to delve into the Zend
side of PHP, so I have no idea how that all works. I'll put in a
request and see what happens.

Thanks,
Blake

Ben Becker

unread,
Feb 13, 2012, 5:24:01 AM2/13/12
to mongodb-dev
On Feb 9, 9:24 pm, Blake Stovall <bstov...@bstovall.com> wrote:
> I'd like to extend MongoCursor to override a couple of methods and add
> some minor functionality.

For this use case, would it be possible to use PHP's methods like
__call() and __callStatic() to return the wrapper (ala multiple
dispatch)? Something like:

Class MyMongoCollection
{
public function __construct(MongoCollection $collection) {
$this->collection = $collection
}
public function __call($name, $arguments) {
switch($name) {
case "find":
case "findOne":
case "update":
case "insert":
return new
MyResultSet(call_user_func_array(array($collection, $name),
$arguments));
break;
}
}
...
}

// Then you could get your extended result set by doing something
like:
$m = new Mongo('hostname:port');
$collection = new MyMongoCollection($m->selectDB('dbname'));
$myCustomResultObject = $collection->find(...);

Functions like find() would return a ResultSet instead of a
MongoCursor in this example. It should be possible to apply this any
object including MongoDB, MongoCollection and MongoCursor. This is
untested code based based off of http://php.net/manual/en/language.oop5.overloading.php
and http://us2.php.net/manual/en/function.call-user-func-array.php.
Hope this helps.

Regards,
Ben

Blake Stovall

unread,
Feb 13, 2012, 6:42:57 PM2/13/12
to mongodb-dev


On Feb 13, 4:24 am, Ben Becker <benjamin.bec...@gmail.com> wrote:
> On Feb 9, 9:24 pm, Blake Stovall <bstov...@bstovall.com> wrote:
>
> > I'd like to extend MongoCursor to override a couple of methods and add
> > some minor functionality.
>
> For this use case, would it be possible to use PHP's methods like
> __call() and __callStatic() to return the wrapper (ala multiple
> dispatch)?  Something like:


Well, it addresses another problem, but not the one the functionality
I asked about solves.

Blake

Blake Stovall

unread,
Feb 13, 2012, 6:47:06 PM2/13/12
to mongodb-dev
I take that back. The same concept could be used in the ResultSet
class to redirect some calls to the ResultSet class and passing the
others through to the MongoCursor class. It's still a hacked solution
compared to being able to extend a class directly (as are most
solutions that utilize __get, __set, and __call).

Blake

Derick Rethans

unread,
Feb 14, 2012, 4:25:08 AM2/14/12
to mongodb-dev
On Mon, 13 Feb 2012, Blake Stovall wrote:

> On Feb 13, 5:42 pm, Blake Stovall <bstov...@bstovall.com> wrote:
> > On Feb 13, 4:24 am, Ben Becker <benjamin.bec...@gmail.com> wrote:
> >
> > > On Feb 9, 9:24 pm, Blake Stovall <bstov...@bstovall.com> wrote:
> >
> > > > I'd like to extend MongoCursor to override a couple of methods and add
> > > > some minor functionality.
> >
> > > For this use case, would it be possible to use PHP's methods like
> > > __call() and __callStatic() to return the wrapper (ala multiple
> > > dispatch)?  Something like:
> >
> > Well, it addresses another problem, but not the one the functionality
> > I asked about solves.
>

> I take that back. The same concept could be used in the ResultSet
> class to redirect some calls to the ResultSet class and passing the
> others through to the MongoCursor class. It's still a hacked solution
> compared to being able to extend a class directly (as are most
> solutions that utilize __get, __set, and __call).

Yeah, and it is also slower because it incurs calling yet another PHP
function.

cheers,
Derick

--
http://mongodb.org | http://derickrethans.nl
twitter: @derickr and @mongodb

Reply all
Reply to author
Forward
0 new messages