I've been going over PDO lately and I noticed that PDO::query() always
returns a PDOStatement object. Now for the most part, this is fine, but
it got me thinking.
It's been said many times that PDO is not an abstraction layer, it's
more of a unified interface, however, having PDO::query() always return
a PDOStatement object means that any abstraction that uses PDO will
either a) have to use PDOStatement as it's result set object (which
while fine for the most part, kind of defeats the idea that PDO is not
an abstraction layer) or b) create it's own result set object and
populate it from the returned PDOStatement result set. Option "b" is
somewhat of a waste since it involves the instantiation of two objects
for the same purpose.
What I'm proposing is to allow PDO::query() to return a subclass of
PDOStatement. This would allow abstractions to tailor the result set to
their own needs while not (in theory) being too complicated to implement.
My initial idea involves passing an object that is a subclass of
PDOStatement into PDO:query as a second parameter, then all that would
be needed to get it to return a custom result set would be something
like this:
$results = $conn->query($sql,new ResultSet());
If I knew C, I'd write a patch for this, but since I don't, I thought
I'd at least suggest this.
Nicholas Telford
Nicholas Telford wrote:
What I'm proposing is to allow PDO::query() to return a subclass of
PDOStatement. This would allow abstractions to tailor the result set to
their own needs while not (in theory) being too complicated to implement.My initial idea involves passing an object that is a subclass of
PDOStatement into PDO:query as a second parameter, then all that would
be needed to get it to return a custom result set would be something
like this:
http://oss.backendmedia.com/index.php?area=PDO&page=FAQ
read the last item over there.
Marcus (IIRC) is planning on making this less clumsy as right now you
have to repeatedly specifiy the statement class you want AFAIK.
regards,
Lukas
Lukas Smith wrote:
Nicholas Telford wrote:
What I'm proposing is to allow PDO::query() to return a subclass of
PDOStatement. This would allow abstractions to tailor the result set
to their own needs while not (in theory) being too complicated to
implement.My initial idea involves passing an object that is a subclass of
PDOStatement into PDO:query as a second parameter, then all that
would be needed to get it to return a custom result set would be
something like this:http://oss.backendmedia.com/index.php?area=PDO&page=FAQ
read the last item over there.
Marcus (IIRC) is planning on making this less clumsy as right now you
have to repeatedly specifiy the statement class you want AFAIK.regards,
Lukas
Ah thank you, I understand that PDO is still under development, I
thought I may as well mention this before the cement dries so to speak.
Good to see that this has already been thought of and an implementation
already exists (even if it's not ideal).
Just like extending any other built-in class, you need to be careful
to not override built-in methods that either exist now or may exist in
the future; you can very easily burn yourself 6 months down the track
this way.
It's generally a bad idea, and definitely something to avoid if you
are building a class library.
You have now been warned that the traffic is dangerous; if you want to
go play in it, it's your choice :-)
--Wez.
Nicholas Telford wrote:
What I'm proposing is to allow PDO::query() to return a subclass of
PDOStatement. This would allow abstractions to tailor the result set to
their own needs while not (in theory) being too complicated to implement.My initial idea involves passing an object that is a subclass of
PDOStatement into PDO:query as a second parameter, then all that would
be needed to get it to return a custom result set would be something
like this:http://oss.backendmedia.com/index.php?area=PDO&page=FAQ
read the last item over there.
Marcus (IIRC) is planning on making this less clumsy as right now you
have to repeatedly specifiy the statement class you want AFAIK.regards,
Lukas
Wez Furlong wrote:
Just like extending any other built-in class, you need to be careful
to not override built-in methods that either exist now or may exist in
the future; you can very easily burn yourself 6 months down the track
this way.It's generally a bad idea, and definitely something to avoid if you
are building a class library.You have now been warned that the traffic is dangerous; if you want to
go play in it, it's your choice :-)--Wez.
The same could be said for using an external Framework or library
(except that they'd have the luxury of protecting important methods with
"final").
I take it parent::method() works with built-in classes?
Nicholas Telford wrote:
Wez Furlong wrote:
It's generally a bad idea, and definitely something to avoid if you
are building a class library.You have now been warned that the traffic is dangerous; if you want to
go play in it, it's your choice :-)
The same could be said for using an external Framework or library
(except that they'd have the luxury of protecting important methods with
"final").I take it parent::method() works with built-in classes?
err Wez do you think this should really be the case? This will make the
idea that further levels of abstraction be implemented in userland kinda
needlessly hard. This will mean that you need to wrap rather than
extend. Or let me rephrase: I would very much appreciate it if an
explicit extra effort (triple E) would be made to prevent these kind of
situations. Obviously as new functionality is added there might be
issues. Then again atleast we two dont seem to have a large overlap in
method naming :-)
regards,
Lukas
parent::method() should work, but the point is that if you add a foo()
method in a class that extends PDO, at a time where there is no
PDO::foo(), and you make it work in a particular way, and 6-18 months
later, when PDO::foo() gets added and does something totally
different. Now, someone else is consuming your library and hasn't yet
used your foo() implementation, they read the PDO manual and spot the
official PDO::foo() method and wonder why it doesn't work right.
Even more of a headache is that drivers can magically add methods to
the namespace; different methods may be present on an instance (via
call overloading) depending on which driver is in use. These are not
visible via reflection.
This is a classic namespacing problem. We've solved this internally
be forcing drivers to prefix their methods with the driver name. Any
non-prefixed method names are reserved for future use by PDO.
If you don't follow this guideline, your code is officially broken :-)
--Wez.
Wez Furlong wrote:
Just like extending any other built-in class, you need to be careful
to not override built-in methods that either exist now or may exist in
the future; you can very easily burn yourself 6 months down the track
this way.It's generally a bad idea, and definitely something to avoid if you
are building a class library.You have now been warned that the traffic is dangerous; if you want to
go play in it, it's your choice :-)--Wez.
The same could be said for using an external Framework or library
(except that they'd have the luxury of protecting important methods with
"final").I take it parent::method() works with built-in classes?
Wez Furlong wrote:
parent::method() should work, but the point is that if you add a foo()
method in a class that extends PDO, at a time where there is no
PDO::foo(), and you make it work in a particular way, and 6-18 months
later, when PDO::foo() gets added and does something totally
different. Now, someone else is consuming your library and hasn't yet
used your foo() implementation, they read the PDO manual and spot the
official PDO::foo() method and wonder why it doesn't work right.Even more of a headache is that drivers can magically add methods to
the namespace; different methods may be present on an instance (via
call overloading) depending on which driver is in use. These are not
visible via reflection.This is a classic namespacing problem. We've solved this internally
be forcing drivers to prefix their methods with the driver name. Any
non-prefixed method names are reserved for future use by PDO.If you don't follow this guideline, your code is officially broken :-)
--Wez.
Unless the developer of said library realised this problem and decided
to prefix all his/her methods with something unique :-P
I understand what you're saying, and it is a bit of a problem, however,
it's something that other Object-Oriented languages must also suffer
when users decide to subclass a built in class, or even one from an
external library. In fact, this problem would be present anywhere where
someone would be subclassing a class that is not under their direct control.
So I guess the moral of the story is, it's possible, just be careful
with method naming :-)