Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: 7 PDO fetch(All) tries to convert types to associated type

Tags:

php

pdo

Today I found out that our code appears to be backward incompatible with a change in PDO. In PHP <5.6 the result sets from a PDOStatement through its functions fetch and fetchAll returned rows whose values where either a string or null. Our code relies on this attribute.

A while ago we updated to PHP 7. It turns out that PDO now attempts to convert some datatypes to other associated types. For example, a FLOAT column creates a float value in the PDOStatement result set. And a TINYINT column creates an integer value in the result set. Interestingly, a BIGINT or a large INT UNSIGNED shows up as a string when it cannot be displayed as an integer and certain other types (such as DECIMAL) are not converted to anything. They remain strings. I thought it was a generally agreed upon principle that converting data types from a MySQL database to PHP data types is problematic and should not be carried out by PHP itself, but apparently PHP 7 decided otherwise.

So PHP 7's PDO introduces a set of conversion rules that it uses internally to convert values selected from a database, but that screws up my code base and because of the inconsistencies of these conversion rules, I'd rather not change my code base to suit them. Is there maybe some sort of setting or flag which I can toggle to prevent PDO from converting the values it fetches?

like image 729
user2180613 Avatar asked Sep 14 '16 13:09

user2180613


People also ask

How fetch data from database in PHP and display PDO?

Fetch data from a result set by calling one of the following fetch methods: To return a single row from a result set as an array or object, call the PDOStatement::fetch method. To return all of the rows from the result set as an array of arrays or objects, call the PDOStatement::fetchAll method.

What does PDO fetchAll return?

PDOStatement::fetchAll() returns an array containing all of the remaining rows in the result set. The array represents each row as either an array of column values or an object with properties corresponding to each column name. An empty array is returned if there are zero results to fetch.

What is PDO :: Fetch_assoc?

PDO::FETCH_ASSOC. Returns an array indexed by column name as returned in your result set. PDO::FETCH_BOTH (default) Returns an array indexed by both column name and 0-indexed column number as returned in your result set.

What is PDO :: Fetch_obj?

PDO::FETCH_NUM. Returns an array indexed by column number as returned in your result set, starting at column 0. PDO::FETCH_OBJ. Returns an anonymous object with property names that correspond to the column names returned in your result set.


1 Answers

It is not PHP7 but the underlying driver called mysqlnd.
Also, it is not a set of conversion rules but the way the transport protocol works: when both mysqlnd and native prepatred statements are used, then the binary transport protocol is used, means there is always an information about the data type. So the data just gets unpacked from the binary format right into a variable of the proper type - when PHP has an appropriate one, namely INTs and FLOATs (note that for the DECIMAL type string is returned, due to nature of this type).

In case you don't want this behavior, there is a configuration option for this

$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);

will revert this behavior to just strings and nulls as before

like image 194
Your Common Sense Avatar answered Nov 07 '22 05:11

Your Common Sense