Problems with Json Encode of PHP?

0

Something strange is occurring at the output of my function. When using the var_dump only on the variable it returns key and value normally. Piece of code:

public function buildGender()
{
    $unknow_name = array();

    foreach ( $this->author_comment as $key => $value) 
    {
        $first_name = split(' ',$value);

        if  ( isset( $this->genders[ trim( $first_name[ 0 ] ) ] ) )
        {                
            $this->gender_comment[$key] = $this->genders[$first_name[0]];
        }
        else
        {
            $this->gender_comment[$key] = '0';
            $unknow_name[] = $first_name[0];
        }

    }

    foreach ( $this->author_reply as $key => $value) 
    {
        $first_name = split( ' ',$value );

        if  ( isset( $this->genders[ trim( $first_name[0] ) ] ) ) 
        {                
            $this->gender_reply[$key] = $this->genders[$first_name[0]];
        }
        else
        {
            $this->gender_reply[$key] = '0';
            $unknow_name[] = $first_name[0];
        }
    }

    foreach ( $unknow_name as $key ) 
    {
        $PDO = Database::connect();
        $SQL = "INSERT INTO sys_name_gender ( name,classification ) VALUES (?,?) on conflict(name) do nothing";
        $DATA = array($key,'0'); 
        $SQL  = $PDO->prepare($SQL);
        $SQL->execute($DATA);
        $PDO = Database::disconnect();
    }

    //var_dump(array_count_values($this->gender_comment)  );
    echo json_encode( array( 'gender_reply' => array_count_values( $this->gender_reply ), 'gender_comment' => array_count_values( $this->gender_comment ) ) );

}

This function takes the first name, compares it with my database of classified names and if it returns a string 0 | 1 | 2 . If it is 0 it inserts the name to be sorted in the future.

The output looks like this:

{"gender_reply":{"1":3,"0":24,"2":4},"gender_comment":[5341,358,3478]}

would have to look like this:

{"gender_reply":{"1":3,"0":24,"2":4},"gender_comment":{"1":358,"0":5341,"2":3478}}

In var_dump it correctly shows the keys and values, this by taking only json_encode

Does anyone know why you format this JSON?

looks like this:

$_gender_reply   = array_count_values( $this->gender_reply );
        $_gender_comment = array_count_values( $this->gender_comment );

        $_zero = $_gender_comment['0']+$_gender_reply['0'];
        $_one  = $_gender_comment['1']+$_gender_reply['1'];
        $_two  = $_gender_comment['2']+$_gender_reply['2'];
        $total = $_zero+$_one+$_two; 

        echo json_encode( array( 'total' => $total-$_zero, '%homem' => number_format($_one/($total-$_zero)*100,'2'), '%mulher' => number_format($_two/($total-$_zero)*100,'2') ) );

It worked perfectly, but I wondered why it did not mount the JSON correctly.

    
asked by anonymous 21.09.2016 / 15:15

1 answer

2

When array indexes are all numeric, json_enconde() does not return the "chave":"valor" pair and displays only the values, sorted by index.

A clearer example:

$array = array(0 => 5341, 1 => 358, 2 => 3478);
echo json_encode($array);

Return:

{[5341,358,3478]}

If a non-numeric key exists:

$array = array(0 => 5341, 1 => 358, 2 => 3478, 'foo' => 444);

Returns the "chave":"valor"

{"0":5341,"1":358,"2":3478,"string":444}

To display the array keys with numeric-only indexes, you can use the second parameter with the value of the JSON_FORCE_OBJECT constant.

$array = array(0 => 5341, 1 => 358, 2 => 3478);
echo json_encode($array, JSON_FORCE_OBJECT);

Return:

{"0":5341,"1":358,"2":3478}

See: link

To clear up doubts, I ran a test simulating what I'm supposed to have in the array, as described in the question:

//5341,358,3478
//$arr = array('0', '0', '0', '1', '1', '1');
for ($i = 1; $i <= 5341; $i++) {
    $arr[] = 0;
    if ($i <= 358) {
        $arr[] = 1;
    }
    if ($i <= 3478) {
        $arr[] = 2;
    }
}
//var_dump(array_count_values($arr));
//echo PHP_EOL.PHP_EOL.PHP_EOL.json_encode(array_count_values($arr));
echo PHP_EOL.PHP_EOL.json_encode(array_count_values($arr), JSON_FORCE_OBJECT);

I did this because the array is large, it has about 9,000 values. So I thought it might be something with memory, but the result gave what was expected. Since the keys are numeric, json_encode() returns only the values.



obs: Numeric keys in an array are only integers. Fractional numbers are ignored.

    
21.09.2016 / 18:52