Allow PDO::query() to return a subclass of PDOStatement

php.internals

Nicholas Telford

21 years ago
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

Lukas Smith

21 years ago
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

Nicholas Telford

21 years ago
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).

Wez Furlong

21 years ago
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. On 5/18/05, Lukas Smith <lsmith@php.net> wrote:

Nicholas Telford

21 years ago
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

21 years ago
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. On 5/18/05, Nicholas Telford <nick.telford@ntlworld.com> wrote:

Nicholas Telford

21 years ago
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 :-)

Lukas Smith

21 years ago
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