'exclude some values in json_encode() with JSON_NUMERIC_CHECK

I use CakePHP framework. I have an array which corresponds a model's records. I have to handle it in the way, that all the integers and floats are output as integers and floats just like in java without quotes(111 or 11.1 instead of this '111.1' or '11.1'). I found the way to return all the values in this way: return json_encode($data, JSON_NUMERIC_CHECK);. The question is: is there any way to exclude some numeric fields to be outpt in this way? In other words: I have two numeric fields: field1 and field2, and they have to be with quotes. Meantime all other numeric fields must be without quotes. How could I implement this ? My array looks so:

array(
    (int) 0 => array(
        'password' => '*****',
        'id' => '2',
        'number' => '2',
        'debtor_number' => null,
        'name' => 'Ziegler',
        'firstname' => 'Lisa',
        'address' => 'Frau',
        'title' => '',
        'name_extension' => '',
        'company' => '',
        'company_function' => '',
        'street' => 'Feldbergstr. 13-15',
        'street2' => null,
        'postbox' => '',
        'street_or_postbox' => '1',
        'zip' => '60318',
        'city' => 'Frankfurt am Main',
),
    (int) 1 => array(
        'password' => '*****',
        'id' => '3',
        'number' => '3',
        'debtor_number' => null,
        'name' => 'Trappatoni',
        'firstname' => 'Günther',
        'address' => 'Herr',
        'title' => '',
        'name_extension' => '',
        'company' => '',
        'company_function' => '',
        'street' => 'Trilluper Weg 17',
        'street2' => null,
        'postbox' => '',
        'street_or_postbox' => '1',
        'zip' => '60594',
        'city' => 'Frankfurt am Main',


Solution 1:[1]

First of all, a little example of how JSON_NUMERIC_CHECK works:

$data = [112, '34', 5.6, '7.8'];
echo json_encode($data) . PHP_EOL;
echo json_encode($data, JSON_NUMERIC_CHECK) . PHP_EOL;

... prints:

[112,"34",5.6,"7.8"]
[112,34,5.6,7.8]

There isn't any feature to determine which values should be parsed (and if they wanted to add it, what would its syntax be?). The only way to get the results you want is to ensure that source data is already using the appropriate PHP data types. And that's something you can certainly do (though the exact details depend on your specs):

$person = [
   'age' => 33,
   'zip_code' => '09007',
];
$person['age'] = is_null($person['age']) ? null : (int)$person['age'];
echo json_encode($person);

... prints:

{"age":33,"zip_code":"09007"}

Solution 2:[2]

Another solution for this issue if it's important enough for you to solve it in a robust way, and that would be to use the JMS Serializer library.

You would need to define a class for your data, but after that, whatever types you have defined via annotation will be honored during serialization.

With that said, Alvaro's post shows that casting will work. So, something like this should also work:

// Fix all Numerics
$data = json_decode(json_encode($data, JSON_NUMERIC_CHECK), true);
// Fix your 2 strings

$callback = function($row) {
    if (array_key_exists('field1', $row)) {
        $row['field1'] = (string)$row['field1'];
    } 

    if (array_key_exists('field2', $row)) {
        $row['field2'] = (string)$row['field2'];
    } 
    return $row;
}

$data = array_map($callback, $data);
// This should be ready for final encode

return json_encode($data);

Solution 3:[3]

I tried this and it worked fine for me because I would only check JSON_NUMERIC_CHECK on id and with this

echo json_encode($article, JSON_NUMERIC_CHECK)

,and I got id and telephone as int.

Try this

if ($result->num_rows > 0) {
 
    while ($row = $result->fetch_assoc()) {
        $row['id'] = (int)$row['id'];
        $row['telephone'] = (string)$row['telephone'];
        $db_data[] = $row;
    }
    //format json
    $article->status = true;
    $article->message = "success";
    $article->employee = $db_data;
    
//return json 
    echo json_encode($article);
} else {
    
}

Solution 4:[4]

l1 = [1, 3, 5, 7, 9]
l2 = [0, 2, 4, 8, 10]
dict(zip(l1, l2))

output:

{1: 0, 3: 2, 5: 4, 7: 8, 9: 10}

Solution 5:[5]

You can use the zip built-in function to combine multiple lists into an iterable of tuples. This zip iterable can be made into a dictionary.

Syntax

for (valueoflist1,valueoflist2) in zip(list1,list2):
   #Code

Code resolution:

result = {key: val for key ,val in zip(keys ,values)}

or

    result = dict(zip(keys, values))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Álvaro González
Solution 2 gview
Solution 3 M E S A B O
Solution 4 Tal Folkman
Solution 5 Simon Crowe