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.

mauvm
  • 3,586
  • 3
  • 18
  • 19
  • 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. – Mark Fox Nov 10 '14 at 21:29
  • @MarkFox I disagree, because of the type conversion overhead (int > string > int). Which costs time and may introduce errors (floating point conversion for example). – mauvm Nov 11 '14 at 10:02
  • Are you sure it's the database driver itself and not at the ORM layer? – Mark Fox Nov 11 '14 at 20:08
  • @mauvm 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? https://support.hypernode.com/knowledgebase/known-compatible-frameworks-extensions-hhvm/ – Gary Green Apr 09 '15 at 09:25
  • 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. – mauvm Apr 09 '15 at 09:43
  • What would be the process for adding mysqlnd support into HHVM? – egekhter Nov 05 '15 at 05:30

3 Answers3

1

Create an accessor for the id in your Post class.

class Post extends Eloquent {

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

}
slapyo
  • 2,979
  • 1
  • 15
  • 24
  • As I said, using model accessors is more of a hack IMO. – mauvm Nov 11 '14 at 09:47
  • 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](http://www.ph-bergsmann.com/typo3/2014/04/04/typo3-with-hhvm/), 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: http://stackoverflow.com/a/24746421/4099592 in order to return the value with the correct type. – slapyo Nov 11 '14 at 16:22
  • 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. – DrewT Apr 05 '15 at 21:42
  • Creating a wrapper is not a hack. It's a perfectly good design decision. – David Apr 26 '15 at 21:38
1

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

hhvm.mysql.typed_results = true

Ian Chadwick
  • 1,547
  • 1
  • 19
  • 21
-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
        ]
    ],
]
Jonathan Amend
  • 12,715
  • 3
  • 22
  • 29
  • 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! – mauvm Nov 11 '14 at 09:54