How to make MySQL driver for HHVM return IDs as integers?
Asked Answered
S

3

11

I noticed that my Laravel API does not return entity identifiers (the primary keys) as integers.

In Api\PostController.php::show():

function index()
{
    $posts = Post::all();

    return $posts;
}

Which returns something like:

[{
    "id": "1",
    "title": "Post one",
    ...
},{
    "id": "2",
    "title": "Post two",
    ...
}]

This messes up my table sorting (because IDs will be sorted as string: 1, 10, 11, 2 etc.).

Dumping the entity itselfs also shows that the id attribute is a string.

As mentioned here the probable cause is that the MySQL driver does not return values in the appropriate type.

I'm using HHVM 3.3.1 on a Ubuntu 14.04 server. Is there any way I can use a native MySQL library (like php5-mysqlnd) for HHVM?

I could use Laravel model accessors to solve the problem. But that is more of a hack IMO.

Please help!


References:


EDIT: I have verified that it's not the ORM layer of Laravel. The PDO instance already returns IDs as strings.

Stumpy answered 7/11, 2014 at 13:2 Comment(6)
Changing your database driver simply to get ints at your application level seems weird: a heavy lift and a longshot for a really simple fix. Enforcing the type at the PHP level (like your ORM, or your app code) makes more sense.Spoils
@MarkFox I disagree, because of the type conversion overhead (int > string > int). Which costs time and may introduce errors (floating point conversion for example).Stumpy
Are you sure it's the database driver itself and not at the ORM layer?Spoils
@Stumpy old question, but just wondered if you managed to solve? It seems HHVM lists mysqlnd as a native PHP driver that's compatible. Should just be a case of installing it on the server, like you would with PHP? support.hypernode.com/knowledgebase/…Einberger
Not yet. I've since then used the fix proposed by @slapyo. It still bugs me though, so if you find the solution please let me know! Note that the page has been last updated 5 months ago. Maybe the problem no longer exists in newer versions of HHVM.Stumpy
What would be the process for adding mysqlnd support into HHVM?Farther
V
1

Create an accessor for the id in your Post class.

class Post extends Eloquent {

    public function getIdAttribute($value)
    {
        return (int)$value;
    }

}
Vertievertiginous answered 10/11, 2014 at 21:0 Comment(4)
As I said, using model accessors is more of a hack IMO.Stumpy
MySQL is returning data, not types. Someone said if you're on Ubuntu you can install the MySQL native driver and it will return the data with the type. According to this post, TYPO3 with HHVM and FPM fallback, you can run the native driver in Ubuntu. If this works for you great, but this will only help those on Ubuntu. Otherwise Laravel would need to implement something similar to this: https://mcmap.net/q/156241/-mysql-integer-field-is-returned-as-string-in-php in order to return the value with the correct type.Vertievertiginous
Normally when you access SQL from a framework you get your data back as an array, an object, or a string. If you want data back specifically as an int either formulate your own idiosyncratic connection + query or else type cast your returned data as an int. This is not a hack, this is the normal reality of returning data from a query.Railroader
Creating a wrapper is not a hack. It's a perfectly good design decision.Arielle
S
1

You need to set typed_results in your /etc/hhvm/php.ini file.

hhvm.mysql.typed_results = true

Sermonize answered 30/12, 2015 at 11:21 Comment(0)
F
-1

I don't have HHVM set up to test, but the fix in PHP would be to disable PDO::ATTR_EMULATE_PREPARES. For example, in your database config file, add:

'connections' => [
    'mysql' => [
        // ...
        'options' => [
            PDO::ATTR_EMULATE_PREPARES => false
        ]
    ],
]
Federal answered 11/11, 2014 at 1:4 Comment(1)
Unfortunately, no such luck. The manual also says "It will always fall back to emulating the prepared statement if the driver cannot successfully prepare the current query.", maybe that's where it goes wrong. Thanks for the suggestion though!Stumpy

© 2022 - 2024 — McMap. All rights reserved.