PHP json_encode with boolean and decimal values

4

I have a PHP function that gets data from the database and returns an array with the results. This array by default has all the data as a string , however some fields should be treated as boolean while others should be treated as values (money) and are of type decimal .

Later I make use of this data in the HTML page to perform some functions or data display. For example:

  • valor - type _decimal (10,2) - Used to display the value of a product.
  • ativo - type tinyint - Used to mark or not a checkbox.

The array of data I get is generated through a query (SELECT) to the database, so the return comes with all fields in string . This "solves" a part of the problem, since it keeps the valor field to the decimal places. The problem starts when I try to convert, using flags in json_encode , transform values back to boolean (or int ), and so I have these 2 cases:

Case 1: When I use json_encode($resposta,JSON_NUMERIC_CHECK) the column valor loses its decimals and is rounded. Ex: 9.90 (string) - > 10 (int)

Case 2: When I use json_encode($resposta,JSON_PRESERVE_ZERO_FRACTION ) the column ativo comes as a string and therefore I can not control the checkbox .

Is there any way around this?

    
asked by anonymous 07.11.2016 / 16:45

2 answers

5

Bringing the code I wrote in the comments here. A simpler solution than trying to coordinate the flags of json_encode() is to treat the values before move to the function.

In this case, if ativo must be a int or bool and valor must be a string, you only need to treat the asset and no flag is required, since in the output of your SQL all values come as string :

$produtos = array(
    array(
        'valor'=> "1.95",
        'ativo'=> '1'
    ),
    array(
        'valor' => '9.90',
        'ativo' => '0'
    ),
);

foreach( $produtos as $produto ) {
    $produto['ativo'] = abs($produto['ativo']);
    $resposta[] = $produto;
}

echo json_encode( $resposta );

Result:

[{"valor":"1.95","ativo":1},{"valor":"9.90","ativo":0}]

If you needed to convert a value to string you could also use 'valor' => (string) 1.95 for example.

    
07.11.2016 / 21:00
0

I tested to demonstrate that there is no difficulty with decimals or booleans when converting to json format.

<?php

$x = array(9.9, 0);

$j = json_encode($x);
?>
<script>
v = JSON.parse('<?php echo $j;?>');
//document.write(v[0]);

if (v[1]) {
    s = 'verdadeiro';
} else {
    s = 'falso';
}

document.write(s);
</script>

Your question does not clarify where and how comparisons of Boolean values do, but by comments it seems to be with JavaScript.

For JavaScript, the value 1 is true and the value 0 is false when they are numeric values. If it is of type string v = '0' , for example, v will be taken as true .

To "dribble" this can solve with the function parseInt() .

<?php

$x = array(9.9, '0');

$j = json_encode($x);
?>
<script>
v = JSON.parse('<?php echo $j;?>');
//document.write(v[0]);

if (parseInt(v[1])) {
    s = 'verdadeiro';
} else {
    s = 'falso';
}

document.write(s);
</script>

As for the decimal value, it can come as a database string that will make no difference.

However, to provide consistency with mathematical operations in JavaScript, convert with the parseFloat() function when you need to do mathematical operations.

a = '9.9';
b = 3;
document.write(parseFloat(a) + b);

Just out of curiosity, for PHP it's similar. Only rename functions. It would be intval() and floatval() .

Of course, I disregard the comparison that checks the type of the variable. if (v === true) { , for example, needs another more appropriate treatment. But the important thing is that you do not have to mess around with json_encode() for both.

    
07.11.2016 / 18:14