5
votes

It is somewhat common knowledge that with different versions of php and mysql, and by using native prepared statements or emulated prepared statements it is possible to have natine value types or not, like this:

$value = $db->query("SELECT 1033 AS Code")->fetch(PDO::FETCH_COLUMN)
$value2 = $db->query("SELECT '1033' AS Code")->fetch(PDO::FETCH_COLUMN);

//PDO::ATTR_EMULATE_PREPARES set to true:
var_dump($value); // string(4) "1033"
var_dump($value2); // string(4) "1033"

//PDO::ATTR_EMULATE_PREPARES set to false:
var_dump($value); // int(1033)
var_dump($value2); // string(4) "1033"

from this article:

The problem is that PDO causes a zval-separation due to a type cast to string. The cast is requested by the PDO core.

PDO will always cast data to string by default and the PDO_MYSQL driver can only work around this PDO default by returning zvals.

Why does PDO will always cast data to string?

1
I always thought it was because not all builds of PHP supported 64-bit integers, so there would be no way to return a BIGINT in native PHP format. But perhaps in more recent versions of PHP (required by mysqlnd), this has changed.Bill Karwin

1 Answers

3
votes

Provided that

PDO will emulate prepared statements/bound parameters for drivers that do not natively support them

... this feature (emulated prepared statements) is probably handled by a piece of code that is common to all drivers.

However, based on the fact that functions like PDOStatement::getColumnMeta() are not implemented for all drivers,

Not all PDO drivers support PDOStatement::getColumnMeta().

... I assume that the PDO common code base is unable to determine the database column type in a consistant, cross-database manner, and therefore must fall-back to a generic string type.

Unfortunately, the source code is far too obscure for me to verify these assumptions.