Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm running into a strange problem when indexing the array numerically with the function array_values, and than encoding it into JSON. Here is a quick explanation how my script operates. Firstly, it fetches data via query from the database and prints the following out:

Eg:

Array
(
[0] => Array
    (
        [label] => Direct
        [value] => 1445
    )

[1] => Array
    (
        [label] => Internal
        [value] => 2
    )

[2] => Array
    (
        [label] => Internal
        [value] => 2
    )

[3] => Array
    (
        [label] => Internal
        [value] => 3
    )

[4] => Array
    (
        [label] => Internal
        [value] => 1
    )

[5] => Array
    (
        [label] => Internal
        [value] => 1
    )

[6] => Array
    (
        [label] => External
        [value] => 1
    )

)

Than with this function I remove any duplicate label's and sum up the value.

$sources  = array();

foreach($data as $key => $values)
{
    if(array_key_exists($values['label'], $sources))
    {
        $sources[$values['label']]['value'] += $values['value'];
        $sources[$values['label']]['label'] = $values['label'];
    }
    else
    {
        $sources[$values['label']]  = $values;
    }
}

Returning this:

Array
(
[Direct] => Array
    (
        [label] => Direct
        [value] => 1445
    )

[Internal] => Array
    (
        [label] => Internal
        [value] => 9
    )

[External] => Array
    (
        [label] => External
        [value] => 1
    )

 )

Note: I can't use SQL to SUM up the total value as the labels direct, internal, and external are assigned after the data is pulled; so please don't suggest it.

Than, I apply array_values() to the returned filtered array, giving me this:

Array
(
[0] => Array
    (
        [label] => Direct
        [value] => 1445
    )

[1] => Array
    (
        [label] => Internal
        [value] => 9
    )

[2] => Array
    (
        [label] => External
        [value] => 1
    )

)

So far everything is good. However, when I turn the array into JSON with json_encode it returns the following string:

[{"label":"Direct","value":"1445"},{"label":"Internal","value":9},{"label":"External","value":"1"}]

On first glance it looks perfectly fine. However, if you look carefully the value 9 is not in quotes, while the values 1445 and 1 are. I need value 9 to be also in quotes.

What I did notice is the problem most likely lies in the function the removes duplicates and sums the values up, as Internal is the only one with duplicates in the orginal array.

Full Code:

//Add up values of duplicate labels 
$sources  = array();

foreach($data as $key => $values)
{
    if(array_key_exists($values['label'], $sources))
    {
        $sources[$values['label']]['value'] += $values['value'];
        $sources[$values['label']]['label'] = $values['label'];
    }
    else
    {
        $sources[$values['label']]  = $values;
    }
}

//Assign numeric values as main key
$sources = array_values($sources);


//Print JSON
echo json_encode($sources);
share|improve this question
    
Can you show us your json_encode() call? –  Amal Murali Nov 6 '13 at 15:55
    
After the funtion which returns the array assigned to $sources I have the following: $sources = array_values($sources); echo json_encode($sources); –  Bob Jansen Nov 6 '13 at 15:57
1  
if you use var_dump instead of print_r, you can see more information about the data type –  Aaron Gong Nov 6 '13 at 16:05

1 Answer 1

up vote 1 down vote accepted

What I did notice is the problem most likely lies in the function the removes duplicates and sums the values up, as Internal is the only one with duplicates in the original array.

Yes. That is the issue. When you get values from a database, they are usually strings. So, your values are all strings. (NOTE: Use var_dump for debugging, it'll show you the types of your values.)

When you do the addition, they are converted to ints ('1'+'2' = 3). So, that's why 9 is not in quotes, but the others are.

share|improve this answer
    
How would I convert them back to strings? –  Bob Jansen Nov 6 '13 at 15:59
    
$var = (string)$var; –  Acácio Veit Schneider Nov 6 '13 at 16:00
3  
Numbers are also valid JSON, so the JSON is not incorrect. Depending upon how the values are used, it may cause problems. –  Explosion Pills Nov 6 '13 at 16:00
2  
if you want to convert to string, you need to iterate through and change all the ...['value'] to string. you can try ...['value'] = strval(...['value']); –  Aaron Gong Nov 6 '13 at 16:01
2  
@BobJansen: You'd have to loop over the array and convert them back: foreach($sources as &$val){ $val['value'] = "{$val['value']}"; }. There's no way to automatically do it. There's JSON_NUMERIC_CHECK (json_encode($sources, JSON_NUMERIC_CHECK);), but that's the opposite of what you want. That will convert the strings to numbers! –  Rocket Hazmat Nov 6 '13 at 16:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.