开发者

CSV to JSON with PHP?

I need to convert a CSV file to JSON on the server using PHP. I am using this script which works:

function csvToJSON($csv) {
    $rows = explode("\n", $csv);

    $i = 0;
    $len = count($rows);
    $json = "{\n" . '    "data" : [';
    foreach ($rows as $row) {
        $cols = explode(',', $row);
        $json .= "\n        {\n";
        $json .= '            "var0" : "' . $cols[0] . "\",\n";
        $json .= '            "var1" : "' . $cols[1] . "\",\n";
        $json .= '            "var2" : "' . $cols[2] . "\",\n";
        $json .= '            "var3" : "' . $cols[3] . "\",\n";
        $json .= '            "var4" : "' . $cols[4] . "\",\n";
        $json .= '            "var5" : "' . $cols[5] . "\",\n";
        $json .= '            "var6" : "' . $cols[6] . "\",\n";
        $json .= '            "var7" : "' . $cols[7] . "\",\n";
        $json .= '            "var8" : "' . $cols[8] . "\",\n";
        $json .= '            "var9" : "' . $cols[9] . "\",\n";
        $json .= '            "var10" : "' . $cols[10] . '"';
        $json .= "\n        }";

        if ($i !== $len - 1) {
            $json .=开发者_如何学JAVA ',';
        }

        $i++;
    }
    $json .= "\n    ]\n}";

    return $json;
}

$json = csvToJSON($csv);
$json = preg_replace('/[ \n]/', '', $json);

header('Content-Type: text/plain');
header('Cache-Control: no-cache');
echo $json;

The $csv variable is a string resulting from a cURL request which returns the CSV content.

I am sure this is not the most efficient PHP code to do it because I am a beginner developer and my knowledge of PHP is low. Is there a better, more efficient way to convert CSV to JSON using PHP?

Thanks in advance.

Note. I am aware that I am adding whitespace and then removing it, I do this so I can have the option to return "readable" JSON by removing the line $json = preg_replace('/[ \n]/', '', $json); for testing purposes.

Edit. Thanks for your replies, based on them the new code is like this:

function csvToJson($csv) {
    $rows = explode("\n", trim($csv));
    $csvarr = array_map(function ($row) {
        $keys = array('var0','var1','var2','var3','var4','var5','var6','var7','var8','var9','var10');
        return array_combine($keys, str_getcsv($row));
    }, $rows);
    $json = json_encode($csvarr);

    return $json;
}

$json = csvToJson($csv);

header('Content-Type: application/json');
header('Cache-Control: no-cache');
echo $json;


Well there is the json_encode() function, which you should use rather than building up the JSON output yourself. And there is also a function str_getcsv() for parsing CSV:

$array = array_map("str_getcsv", explode("\n", $csv));
print json_encode($array);

You must however adapt the $array if you want the JSON output to hold named fields.


I modified the answer in the question to use the first line of the CSV for the array keys. This has the advantage of not having to hard-code the keys in the function allowing it to work for any CSV with column headers and any number of columns.

Here is my modified version:

function csvToJson($csv) {
    $rows = explode("\n", trim($csv));
    $data = array_slice($rows, 1);
    $keys = array_fill(0, count($data), $rows[0]);
    $json = array_map(function ($row, $key) {
        return array_combine(str_getcsv($key), str_getcsv($row));
    }, $data, $keys);

    return json_encode($json);
}


None of these answers work with multiline cells, because they all assume a row ends with '\n'. The builtin fgetcsv function understands that multiline cells are enclosed in " so it doesn't run into the same problem. The code below instead of relying on '\n' to find each row of a csv lets fgetcsv go row by row and prep our output.

function csv_to_json($file){

    $columns = fgetcsv($file); // first lets get the keys.
    $output = array(); // we will build out an array of arrays here.

    while(!feof($file)){ // until we get to the end of file, we'll pull in a new line
        $line = fgetcsv($file); // gets the next line
        $lineObject = array(); // we build out each line with our $columns keys
        foreach($columns as $key => $value){
            $lineObject[$value] = $line[$key];
        }
        array_push($output, $lineObject);
    }
    return json_encode($output); // encode it as json before sending it back
}


Some tips...

  • If you have URL opening enabled for fopen() and wrappers, you can use fgetscsv().
  • You can build an array of the CSV, and then convert it with PHP's native json_encode().
  • The correct mime type for JSON is application/json.


You could probably reduce the overhead by removing all the spaces and \n's. But that's in your note.

You could increase the performance by skipping the preg_replace and passing a boolean that would turn it on and off.

Other than that, the variable unrolling of your var[1-10] actually is good, as long as there are always ten varaibles.

The explode and the foreach approach are just fine.


I recommend using Coseva (a csv parsing library) and using the built in toJSON() method.

<?php

// load
require('../src/CSV.php');

// read
$csv = new Coseva\CSV('path/to/my_csv.csv');

// parse
$csv->parse();

// disco
echo $csv->toJSON();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜