1

I have a testing server with PHP version 5.5.9, and we have a QA server with PHP version 5.6.16.

I am for the sake of this post using the same code branch on both instances (full disclosure: it's a Laravel install but I'm not sure this is a Laravel issue)

On the QA server, an API returns JSON with the integers unquoted as follows (this is simplified):

{["id":1,"name":"John"],["id":2,"name":"Sam"]}

But on my server (the 5.6.16 one), the same exact API call returns:

{["id":"1","name":"John"],["id":"2","name":"Sam"]}

And, Angular is not liking that and does not parse it.

It's not the data

The data and tables the data is coming from are exactly alike in structure - I have verified this.

I don't want to "fix" Angular

Though in theory Angular should handle this(?), I don't want to touch our coding for the front end.

I want the output to be the same..

Regardless of what Angular is doing, the obvious solution is to have the outputs be exactly equal.

What do I do?

  • I want to avoid upgrading PHP on my server - that might open up more problems
  • I am thinking that there is a setting in json_encode() which can be set to change this but I do not know which one.
  • Also there may be a setting in laravel itself which could be at least locally changed on my end. For the record there are well over 100+ json_encode calls in the codebase.
Oliver Williams
  • 5,966
  • 7
  • 36
  • 78
  • 2
    my guess. its how you load the data... and not json_encode() – Roland Starke Mar 09 '17 at 14:18
  • Possible duplicate of http://stackoverflow.com/questions/1390983/php-json-encode-encoding-numbers-as-strings. – localheinz Mar 09 '17 at 14:19
  • maybe this could help you. http://stackoverflow.com/a/9881435/4668162 – Onix Mar 09 '17 at 14:23
  • 2
    If the data comes from the database, it could be related to for example the mysql driver used: http://stackoverflow.com/questions/5323146/mysql-integer-field-is-returned-as-string-in-php – jeroen Mar 09 '17 at 14:26
  • 1
    What @jeroen wrote is 100% the problem you're having. One server probably has mysql native driver for PHP while the other one hasn't. Without `mysqlnd` PHP can't interpret data types so it treats them as strings, hence quoted integers. You **should** update your PHP. The other solution is to manually typecast fields - and that can take up so much time. – Mjh Mar 09 '17 at 15:43
  • 1
    Thanks to @jeroen, and also to @Mjh for specifying the PHP upgrade for the driver. This is the most elegant solution as updating all instances of `json_encode()` would be unreliable and a hack. – Oliver Williams Mar 10 '17 at 09:37

2 Answers2

1

Its not an issue in json_encode() it is what you are encoding that makes a difference. See this simple example

$a = array(
    'id' => 111,
    'astring' => 'test',
    'OhLookItsANumberRecordedAsAString' => '456'
);
$json = json_encode($a);
echo $json;

Result

{"id":111,
 "astring":"test",
 "OhLookItsANumberRecordedAsAString":"456"
}

But if you make sure the integers are integers all is as you expect

$a = array(
        'id' => 111,
        'astring' => 'test',
        'OhLookItsANumberRecordedAsAString' => '456',
        'ANumber' => (int)'456'
    );
$json = json_encode($a);
echo $json;

Result

{"id":111,
 "astring":"test",
 "OhLookItsANumberRecordedAsAString":"456",
 "ANumber":456
}
RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
  • Thanks for the post here but the actual comments below my OP are actually the most prescient. This is not helpful from a standpoint of _why_ the condition is happening. Points for the typecasting though - it would just be hard to update code that way. – Oliver Williams Mar 10 '17 at 09:40
0

As @RiggsFolly it definitely depends on how the source is providing the integer data. If the numbers are quoted from source, json_decoder treats them as a string.

Something you can try: json_encode as a 2nd parameter called $options. Set it to attempt to encode numbers as integers rather than strings.

http://php.net/manual/en/function.json-encode.php

PHP json_encode encoding numbers as strings

Community
  • 1
  • 1
David J Eddy
  • 1,999
  • 1
  • 19
  • 37