1

I have a multidimensional array. I want to convert that array to JSON. I'm using json_encode but it's not working.

Here is the code that I'm using.

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

header('Content-Type: application/json');
include '../panel/config/conn.php';
include '../panel/config/helper_functions.php';

$postions = array(1 => "Goalkeeper", 2 => "Defender", 3 => "Midfielder", 4 => "Forward");
$result = array();
$tmp = get_football_assets($conn);

foreach ($tmp as $key => $value) {
    $pair = strtolower($value['pair']);
    $value['pair'] = $pair;
    $value['position'] = $postions[$value['position_id']];
    unset($value['position_id']);
    $result[$pair] = $value;
}
echo json_encode($result);

** Below Function have been written in helper_functions.php **

function get_football_assets($con){
    $data = array();
    $sql = "SELECT nationality, birthdate, birthcountry, birthplace, height, weight, players.position_id as position_id, players.image_path as image_path, teams.name as club, countries.name as country, feed.pair as pair, feed.fullname as name, feed.price as price from players JOIN feed ON feed.player_id = players.api_id JOIN teams ON teams.api_id = players.team_id JOIN countries ON countries.api_id = players.country_id";
    mysqli_set_charset($con, 'utf8');
    $result = mysqli_query($con, $sql);
    while($rows = mysqli_fetch_assoc($result)){
        $data[] = $rows;
    }
    return $data;
}

If I do print_r($result) then it shows the following result but I'm only showing 3 records since the output has more than 1500 records :-

[sergeaurier95094] => Array
        (
            [nationality] => C�te d'Ivoire
            [birthdate] => 24/12/1992
            [birthcountry] => C�te d'Ivoire
            [birthplace] => Ouragahio
            [height] => 176 cm
            [weight] => 76 kg
            [image_path] => https://cdn.sportmonks.com/images/soccer/players/22/95094.png
            [club] => Tottenham Hotspur
            [country] => C�te d'Ivoire
            [pair] => sergeaurier95094
            [name] => Serge Aurier
            [price] => 10.00
            [position] => Defender
        ),

[davinsons�nchezmina26294] => Array
        (
            [nationality] => Colombia
            [birthdate] => 12/06/1996
            [birthcountry] => Colombia
            [birthplace] => Caloto
            [height] => 187 cm
            [weight] => 81 kg
            [image_path] => https://cdn.sportmonks.com/images/soccer/players/22/26294.png
            [club] => Tottenham Hotspur
            [country] => Colombia
            [pair] => davinsons�nchezmina26294
            [name] => Davinson S�nchez Mina
            [price] => 10.00
            [position] => Defender
        ),

[lucasrodriguesmouradasilva95998] => Array
        (
            [nationality] => Brazil
            [birthdate] => 13/08/1992
            [birthcountry] => Brazil
            [birthplace] => S�o Paulo
            [height] => 172 cm
            [weight] => 72 kg
            [image_path] => https://cdn.sportmonks.com/images/soccer/players/30/95998.png
            [club] => Tottenham Hotspur
            [country] => Brazil
            [pair] => lucasrodriguesmouradasilva95998
            [name] => Lucas Rodrigues Moura da Silva
            [price] => 10.00
            [position] => Midfielder
        )

echo json_last_error_msg(); is returning Malformed UTF-8 characters, possibly incorrectly encoded.

Edit array_map I have removed as suggested and I'm using mysqli_set_charset($con, 'utf8'); but it cannot convert characters like alissonrams�sbecker129820, davinsons�nchezmina26294, nabydecoke�ta32640 etc. etc.

echo bin2hex($pair); gives me the following output :-
6875676f6c6c6f72697331303134

6d696368656c766f726d393737

746f6279616c64657277656972656c64393838

73657267656175726965723935303934

62656e646176696573393839

64616e6e79726f736531323731

646176696e736f6e73e3816e6368657a6d696e613236323934

6b696572616e747269707069657231303136

6a616e766572746f6e6768656e393135

6b796c6577616c6b65722d70657465727334363539

62616d6964656c65616c6c69393232

63687269737469616e64616e6e656d616e6e6572696b73656e393932

6572696364696572393136

6572696b6c616d656c61393431

6c75636173726f647269677565736d6f757261646173696c76613935393938

6d6f75737361736973736f6b6f31333830

686172727977696e6b7331373131

68617272796b616e65393937

6665726e616e646f6c6c6f72656e7465746f7272657331363332

6865756e672d6d696e736f6e34333133

6c756b65616d6f733130363830

7061756c6f64696e6f67617a7a616e69676131343131

766963746f7277616e79616d6131313732

6a75616e6d6172636f73666f797468333335373035

616c66696577686974656d616e333430333436

67656f7267656d61727368353430303835

Actually the problem was strtolower. So the updated code which works fine for me is below :-

foreach ($tmp as $key => $value) {
    mb_internal_encoding('UTF-8');
    $pair = mb_strtolower($value['pair']);
    $value['pair'] = $pair;
    $value['position'] = $postions[$value['position_id']];
    unset($value['position_id']);
    $result[$pair] = $value;
}
header('Content-Type: application/json');
echo json_encode($result);
Alek Stephanok
  • 193
  • 2
  • 17
  • Please provide code that reproduces the problem, with the array encoded in PHP syntax, not as the output of `print_r`. – trincot May 07 '19 at 08:18
  • Add this after json_encode to know exactly what is the error: `switch (json_last_error()) { case JSON_ERROR_NONE: echo ' - No errors'; break; case JSON_ERROR_DEPTH: echo ' - Maximum stack depth exceeded'; break; case JSON_ERROR_STATE_MISMATCH: echo ' - Underflow or the modes mismatch'; break; case JSON_ERROR_CTRL_CHAR: echo ' - Unexpected control character found'; break; case JSON_ERROR_SYNTAX: echo ' - Syntax error, malformed JSON'; break; case JSON_ERROR_UTF8: echo ' - Malformed UTF-8 characters, possibly incorrectly encoded'; break; default: echo ' - Unknown error'; break; }` – Kevin HR May 07 '19 at 08:18
  • 2
    Or just `echo json_last_error_msg();` :-) – trincot May 07 '19 at 08:19
  • Isnt this is discussed here https://stackoverflow.com/questions/8595627/best-way-to-create-an-empty-object-in-json-with-php – Nihir Kumar May 07 '19 at 08:23
  • @Nihir Uhm… OP *doesn't* want an empty object… – deceze May 07 '19 at 08:25
  • 1
    FWIW, `array_map('utf8_encode', $rows)`: *yuck!* See https://stackoverflow.com/a/279279/476 how to get UTF-8 directly from your database. – deceze May 07 '19 at 08:26
  • ^^ that call of `utf8_encode` is almost certainly the cause of your problems. – trincot May 07 '19 at 08:27
  • @trincot It *should* result in valid UTF-8 though, even if the contents may be garbled… – deceze May 07 '19 at 08:28
  • @Alek Look for *non-ASCII* strings in your results (i.e. anything "not English") and show us a sample/experiment with those items. – deceze May 07 '19 at 08:37
  • Try using iconv to convert to UTF8 `function convertUtf8(&$value, $key){ $value = iconv(mb_detect_encoding($value),"UTF-8//IGNORE", $value); } while($rows = mysqli_fetch_assoc($result)){ array_walk($row, 'convertUtf8'); $data[] = $row; }` – Kevin HR May 07 '19 at 08:38
  • @Kevin Ugh, why?! Set your database connection properly to UTF-8 and none of that is necessary. And `mb_detect_encoding` is by definition absolutely unreliable. – deceze May 07 '19 at 08:39
  • @deceze check I have changed the sample array – Alek Stephanok May 07 '19 at 09:14
  • Go through the duplicates for setting yourself up to use UTF-8 properly. – deceze May 07 '19 at 09:23
  • @deceze I'm using ```mysqli_set_charset($con, 'utf8');``` instead of ```array_map``` so It's fine except this cases like **davinsons�nchezmina26294, alissonrams�sbecker129820**. – Alek Stephanok May 07 '19 at 09:27
  • Are those values properly stored in the database in the first place? Do `echo bin2hex($string)` on one of those strings to see what its actual bytes are. – deceze May 07 '19 at 09:29
  • @deceze I did ```echo bin2hex('nabydecoke�ta32640');``` and it returned **6e6162796465636f6b65efbfbd74613332363430**. – Alek Stephanok May 07 '19 at 09:36
  • If you do that with a hardcoded, copy-pasted string, there's no knowing whether that's useful in any way. You will need to use `bin2hex` on one of your results directly. – deceze May 07 '19 at 09:38
  • @deceze So You want me ```echo bin2hex($string)``` inside the loop?? – Alek Stephanok May 07 '19 at 10:03
  • Yes, we need the value of the raw string. – deceze May 07 '19 at 10:11
  • @deceze In my database it is set to **utf8_general_ci** – Alek Stephanok May 07 '19 at 10:42
  • check the updated question – Alek Stephanok May 07 '19 at 10:47
  • @deceze hey actually I understand the problem it is happening because of ```strtolower```. – Alek Stephanok May 07 '19 at 11:16

0 Answers0