Hi,
while testing PDO I was astonished to see that all values (regardless of
their types in the database) are returned as strings (in all extensions
except for PgSQL). Why is that so? It is quite inconsistent, isn't it?
Wasn't PDO supposed to unify the RDBMS access apis?
--
Timm
If it ain't broken, it doesn't have enough features yet
This is by design.
PDO is deliberately very thin on type support, prefering to give the
script author more control over type conversion by using the PHP
built-in type juggling features.
PgSQL returns other types because it is one of 2 drivers that gives
you what it's got, rather than what you ask for. I didn't originally
plan for those two to work that way, it just works out to be more
efficient and less painful for those drivers to do it that.
PDO's goal isn't total unification, but "close-enough unification".
If you want something all-encompassing, you should consider a
heavier-weight abstraction layer, like MDB2.
--Wez.
Hi,
while testing PDO I was astonished to see that all values (regardless of
their types in the database) are returned as strings (in all extensions
except for PgSQL). Why is that so? It is quite inconsistent, isn't it?
Wasn't PDO supposed to unify the RDBMS access apis?--
Timm
If it ain't broken, it doesn't have enough features yet
Timm Friebe wrote:
while testing PDO I was astonished to see that all values (regardless of
their types in the database) are returned as strings (in all extensions
except for PgSQL). Why is that so? It is quite inconsistent, isn't it?
Wasn't PDO supposed to unify the RDBMS access apis?
I dont know the actual implementation but at the last meeting we came to
the conclusion that PDO will pass back proper types if the RDBMS does
and strings if the RDBMS doesnt. Anything more would require the users
from providing this metadata or PDO jumping through alot of hoops to
fetch this information from the RDBMS.
BTW: ibase will probably (eventually) also fall in the sam categorie
because iirc Ard was the one who started the discussion on this at the
last meeting.
regards,
Lukas
Timm Friebe wrote:
while testing PDO I was astonished to see that all values (regardless of
their types in the database) are returned as strings (in all extensions
except for PgSQL). Why is that so? It is quite inconsistent, isn't it?
Wasn't PDO supposed to unify the RDBMS access apis?I dont know the actual implementation but at the last meeting we came to
the conclusion that PDO will pass back proper types if the RDBMS does
and strings if the RDBMS doesnt. Anything more would require the users
from providing this metadata or PDO jumping through alot of hoops to
fetch this information from the RDBMS.
For pdo_mysql (and probably most others), that's one switch statement to
solve them all:) In ext/firebird, the relevant sourcecode is even
#ifdef'd out.
If PDO extensions would returns numbers (int, float) and booleans as
their corresponding PHP datatypes this would save memory. That, for
example, was the main motivation I did this in ext/sybase_ct. There, I
try a best-match policy:
For "integers":
-
If the number "fits" into a long, it will be returned into a long
(PHP datatype integer). This can be done safely for tinyint and
shortint, for example. -
If the number does not fit, I will try to convert it into a double
(PHP datatype float). This is the case for e.g. numeric(10) - values
might not fit. This is the same what PHP does when adding 1 to
LONG_MAX, for instance. If - in the procedure of doing so, strtod()
gives an ERANGE or if the length overflows EG(precision), I will
return a string.
For "floats"
- If the length of the returned value exceeds EG(precision) or if
strtod() returns an ERANGE, I will return a string; a float otherwise.
While this sound like an awful lot of code, it actually boils down to a
couple of lines of C (which will be definitely faster than if users
first fetch column metadata and then "cast" dependant on the information
they retrieve from that).
Talking about that, maybe PDO should start returning Date objects
instead of stupid string representations or sequences of numbers of
those (where users will start preg_match()
ing or strtotime()
ing around
if they want to do arithmetic with the returned value)...
--
Timm
If it ain't broken, it doesn't have enough features yet
- If the number does not fit, I will try to convert it into a double
(PHP datatype float). This is the case for e.g. numeric(10) - values
might not fit. This is the same what PHP does when adding 1 to
LONG_MAX, for instance. If - in the procedure of doing so, strtod()
gives an ERANGE or if the length overflows EG(precision), I will
return a string.
This is exactly what I wanted to avoid. Please don't make this change.
For "floats"
- If the length of the returned value exceeds EG(precision) or if
strtod() returns an ERANGE, I will return a string; a float otherwise.
"Thou shall only return a float if the database passes you back a
float; thou shalt not convert data into the floating point type."
Floats suck. If the database gives you a decimal, pass it back as a string.
Talking about that, maybe PDO should start returning Date objects
instead of stupid string representations or sequences of numbers of
those (where users will startpreg_match()
ing orstrtotime()
ing around
if they want to do arithmetic with the returned value)...
Derick and Pierre have something in mind for the future.
--Wez.
- If the number does not fit, I will try to convert it into a double
(PHP datatype float). This is the case for e.g. numeric(10) - values
might not fit. This is the same what PHP does when adding 1 to
LONG_MAX, for instance. If - in the procedure of doing so, strtod()
gives an ERANGE or if the length overflows EG(precision), I will
return a string.This is exactly what I wanted to avoid.
Why is that so? I think this a good idea - it saves memory in the usual
case (most numbers will probably fit into a long).
Please don't make this change.
How could I? I only have CVS karma for ext/sybase_ct, not for anything
else, not Zend, not PDO:)
--
Timm
If it ain't broken, it doesn't have enough features yet
- If the number does not fit, I will try to convert it into a double
(PHP datatype float). This is the case for e.g. numeric(10) - values
might not fit. This is the same what PHP does when adding 1 to
LONG_MAX, for instance. If - in the procedure of doing so, strtod()
gives an ERANGE or if the length overflows EG(precision), I will
return a string.This is exactly what I wanted to avoid.
Why is that so? I think this a good idea - it saves memory in the usual
case (most numbers will probably fit into a long).
The problem is for the case where the mapping is not 1:1; you end up
changing a 100% precise value into a floating point "guess". String
has a higher fidelity than a float, and PDO prefers hi-fi any day.
Please don't make this change.
How could I? I only have CVS karma for ext/sybase_ct, not for anything
else, not Zend, not PDO:)
ack :)
Well, I meant really that you shouldn't spend time on it :)
--Wez.