php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73650 why lose sql-results their type in PHP?
Submitted: 2016-12-04 14:26 UTC Modified: 2016-12-08 21:55 UTC
From: spam2 at rhsoft dot net Assigned:
Status: Open Package: *Database Functions
PHP Version: 7.0.14 OS:
Private report: No CVE-ID: None
 [2016-12-04 14:26 UTC] spam2 at rhsoft dot net
Description:
------------
declare(strict_types=1); is nice but not helpful when you get from sql-queries *anything* as string and so need to use (int)$row['id_where_i_know_db_type']

on the database server you have int, longint, smallint, tinyint which are clearly int - but why is that information lost and anything casted to a string?


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-04 22:12 UTC] cmb@php.net
-Summary: why lose sql-results there type in PHP? +Summary: why lose sql-results their type in PHP? -Package: Scripting Engine problem +Package: *Database Functions
 [2016-12-04 22:12 UTC] cmb@php.net
I've changed the package to "Database Functions", even though not all database extensions are working this way, see <https://3v4l.org/07TWk>.

And I don't think this is a bug – it's rather something that could be improved. Note that there are some issues, however. Cf. <https://3v4l.org/H1Sel>, for instance (the result could also be a string, but not an int, as the value overflows 64bit signed integers).
 [2016-12-05 01:20 UTC] yohgaki@php.net
Automatic type conversions do harm more than good.

Integers in database may not match PHP internal date types. e.g. PHP's int is only signed 32 bits int under 32 bit architecture. Database's INT8 could unsigned with MySQL/etc. SQLite's type is pseudo type and could be any text even when columns are defined as int/etc.

Converting other system's types to PHP type should not be automatic, but manual. We shouldn't do the same mistake done in JSON again. I'm against to have broken automatic type conversions.

That said, I don't oppose to develop workable type conversion framework.
 [2016-12-05 01:26 UTC] yohgaki@php.net
Not only DBMS, but also almost all inputs are "string". Converting types to appropriate one could be convenient, so I wrote a RFC for it.

https://wiki.php.net/rfc/introduce-type-affinity

The RFC isn't intended to use with database inputs, but this kind of feature may be useful if feature supports some kind of "schema".
 [2016-12-08 19:06 UTC] spam2 at rhsoft dot net
> Integers in database may not match PHP internal 
> date types. e.g. PHP's int is only signed 32 bits 
> int under 32 bit architecture

but how is that different to $row['id'] = (int)$row['id'] which you now must do manually becaus eotherwise sooner or later a function in a class with declare(strict_types=1); will end in a fatal error?
__________________________

inlcude('functions.php');
$row = mysqli_fetch_result($result);
foo($row['id']); 

is a fatal error currently without foo((int)$row['id'])
__________________________

functions.php:

<?php declare(strict_types=1);
 function foo(int $id)
 (
 )
?>
 [2016-12-08 19:26 UTC] cmb@php.net
If there is any chance, that an integer retrieved from a database won't fit into a PHP int, the proper way to deal with this would be something like:

  <?php
  if ($row['id'] >= PHP_INT_MIN && $row['id'] <= PHP_INT_MAX) {
    foo((int) $row['id']);
  } else {
    // uhm, we can't cast $row['id'] to int …
  }
 [2016-12-08 19:37 UTC] spam2 at rhsoft dot net
-PHP Version: 7.0.13 +PHP Version: 7.0.14
 [2016-12-08 19:37 UTC] spam2 at rhsoft dot net
> PHP's int is only signed 32 bits int under 32 bit architecture

show me the machines running in 2016 PHP70/PHP71 under a 32 bit architecture *and* then using declare(strict_types=1); - frankly linux distributions are stopping to build any 32bit stuff at all - there is no RHEL7 even while it ships PHP5.4

how many decades should we accept a doezen potential 32 bit machines stop envolving things? when i develop in strict mode and store a integer to mysql i excpect to get that integer back and not a random string which i have to cast manually or the whole strict_types is pointless because it only leads to fatal errors for no good reasons or you have to use (int) everywhere when something might have came from a database which makes any benefit of typing pointless
 [2016-12-08 19:49 UTC] spam2 at rhsoft dot net
anyways, at that point in time i would be happy if only run-tests.php would respect the environment and not load random configurations not matching the build which is running the test

and the reason for run it directly instead of "make test" is that "make test" has nothing better to do then copy /etc/php.ini instead enforcing a empty default config

https://bugs.php.net/bug.php?id=73609
 [2016-12-08 21:55 UTC] yohgaki@php.net
We cannot ignore 32 bit architecture machines due to raise of IoT. Cheap IoT uses 32 bit CPU and I don't think we have to deal with such architecture while. 

Even with 64 bit CPU, there is signed/unsigned int, numeric data types with db. Converting "int" like value to signed "long" could be wrong.

$myint = (int)$int_like_value_from_somethere;
is not absolutely safe. Programmer has to make sure it's safe, but PHP cannot. (Unless there is way PHP to know it is safe)

In the future, we may have to deal with 128 bit int also. Chances are high we are using 64 bit int at that time.

I don't oppose to have conversion features. In fact, I'm the one proposing type affinity, but type conversions have to be controlled by users(programmers). Otherwise, it cannot work correctly. 

So reasonable choice would be having both "(semi) automatic conversions" and "no conversions" , "no conversion" by default.
 [2017-02-17 12:39 UTC] giunta dot gaetano at gmail dot com
As far as I am concerned, +1 for default type conversion with data from databases, with an optional switch to enable/disable it.

I have read the RFC mentioned above, and tbh I am slightly surprised to see that it mentions conversion of data gotten from HTTP requests as primary usecase, instead of DB APIs.
In my mind, HTTP is a text-based protocol: I always expect data coming in to be an untrusted piece of text, that I have to cast, sanitize, validate. I would be too scared of enabling automatic type casting for that, and would expect a lot of existing code to break.
Otoh, I would expect the correct php types to be gotten from databases as: DBs definitely do have typed data; the int32/64 problem is something that, I think, would pop up more often at design/configuration time rather than runtime; the casting of data gotten from DB is boilerplate code boring enough that I do not think I have ever seen a single dev add to it the check for over/under-flows any way...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 02 03:01:27 2024 UTC