使用 PHP 将 CSV 转换为 JSON

Convert CSV to JSON using PHP

我正在尝试使用 PHP.

将 CSV 文件转换为 JSON

这是我的代码

<?php 

date_default_timezone_set('UTC');
$today = date("n_j"); // Today is 1/23/2015 -> $today = 1_23

$file_name = $today.'.CSV'; // My file name is 1_23.csv
$file_path = 'C:\Users\bheng\Desktop\qb\'.$file_name;
$file_handle = fopen($file_path, "r");

$result = array();

if ($file_handle !== FALSE) {

    $column_headers = fgetcsv($file_handle); 
    foreach($column_headers as $header) {
            $result[$header] = array();

    }
    while (($data = fgetcsv($file_handle)) !== FALSE) {
        $i = 0;
        foreach($result as &$column) {
                $column[] = $data[$i++];
        }
    }
    fclose($file_handle);
}

// print_r($result); // I see all data(s) except the header

$json = json_encode($result);
echo $json;

?>

print_r($result); // I see all data(s)

然后我json_encode($result);并尝试显示它,但屏幕上根本没有任何显示。我所看到的只是空白屏幕和 0 条错误消息。

我做错了什么吗?有人能帮我吗 ?

Added Result of print_r($result);

Array (
    [Inventory] => Array (
        [0] => bs-0468R(20ug)
        [1] => bs-1338R(1ml)
        [2] => bs-1557G(no bsa)
        [3] => bs-3295R(no BSA)
        [4] => bs-0730R-Cy5"
        [5] => bs-3889R-PE-Cy7"
        [6] => 11033R
        [7] => 1554R-A647
        [8] => 4667
        [9] => ABIN731018
        [10] => Anti-DBNL protein 

        .... more .... 

这样试试:

$file="1_23.csv";
$csv= file_get_contents($file);
$array = array_map("str_getcsv", explode("\n", $csv));
$json = json_encode($array);
print_r($json);

我 运行 遇到了类似的问题,我最终使用它在编码为 JSON.

之前将数据递归转换为数组上的 UTF-8
function utf8_converter($array)
{
    array_walk_recursive($array, function(&$item, $key){
        if(!mb_detect_encoding($item, 'utf-8', true)){
                $item = utf8_encode($item);
        }
    });

    return $array;
} 

来自: http://nazcalabs.com/blog/convert-php-array-to-utf8-recursively/

你也可以试试这个方法。

  <?php

function csvtojson($file,$delimiter)
{
    if (($handle = fopen($file, "r")) === false)
    {
            die("can't open the file.");
    }

    $csv_headers = fgetcsv($handle, 4000, $delimiter);
    $csv_json = array();

    while ($row = fgetcsv($handle, 4000, $delimiter))
    {
            $csv_json[] = array_combine($csv_headers, $row);
    }

    fclose($handle);
    return json_encode($csv_json);
}


$jsonresult = csvtojson("./doc.csv", ",");

echo $jsonresult;

如果您正在转换动态 CSV 文件,您可以通过参数 (url=http://example.com/some.csv) 传递 URL,它会显示最新版本:

<?php

// Lets the browser and tools such as Postman know it's JSON
header( "Content-Type: application/json" );

// Get CSV source through the 'url' parameter
if ( isset( $_GET['url'] ) ) {
    $csv = explode( "\n", file_get_contents( $_GET['url'] ) );
    $index = str_getcsv( array_shift( $csv ) );
    $json = array_map(
        function ( $e ) use ( $index ) {
            return array_combine( $index, str_getcsv( $e ) );
        }, $csv
    );
}
else {
    $json = "Please set the path to your CSV by using the '?url=' query string.";
}

// Output JSON
echo json_encode( $json );

data.csv

游戏,技能
寻宝猎人,pilipala
火箭筒,bibobibo
火箭发动机,嘿嘿嘿嘿

要用列名转换,我是这样做的。

csv2json.php

<?php
if (($handle = fopen("data.csv", "r")) !== FALSE) {
    $csvs = [];
    while(! feof($handle)) {
       $csvs[] = fgetcsv($handle);
    }
    $datas = [];
    $column_names = [];
    foreach ($csvs[0] as $single_csv) {
        $column_names[] = $single_csv;
    }
    foreach ($csvs as $key => $csv) {
        if ($key === 0) {
            continue;
        }
        foreach ($column_names as $column_key => $column_name) {
            $datas[$key-1][$column_name] = $csv[$column_key];
        }
    }
    $json = json_encode($datas);
    fclose($handle);
    print_r($json);
}

输出结果

[
    {
        "Game": "Treasure Hunter",
        "Skill": "pilipala"
    },
    {
        "Game": "Rocket Launcher",
        "Skill": "bibobibo"
    },
    {
        "Game": "Rocket Engine",
        "Skill": "hehehohoho"
    }
]

替代解决方案使用与@Whirlwind 的解决方案类似的方法,但returns 更标准的 JSON 结果(每个 object/record 都有命名字段):

// takes a string of CSV data and returns a JSON representing an array of objects (one object per row)
function convert_csv_to_json($csv_data){
    $flat_array = array_map("str_getcsv", explode("\n", $csv_data));

    // take the first array item to use for the final object's property labels
    $columns = $flat_array[0];

    for ($i=1; $i<count($flat_array)-1; $i++){
        foreach ($columns as $column_index => $column){
            $obj[$i]->$column = $flat_array[$i][$column_index];
        }
    }

    $json = json_encode($obj);
    return $json; // or just return $obj if that's a more useful return value
}

接受的答案使用 file_get_contents() 将整个文件作为字符串读取到内存中,然后 explode() 使其成为一个数组。

但它可以变得更快、内存更小、更有用:

function ReadCsv($fn)
{
    $lines= file($fn); // read file directly as an array of lines
    array_pop($lines); // you can remove the last empty line (if required)
    $json= json_encode(array_map("str_getcsv", $lines), JSON_NUMERIC_CHECK);
    print_r($json);
}

Nb:我在这里使用 JSON_NUMERIC_CHECK 来避免数字被双引号引用到字符串中。它还减少了输出大小,并且通常有助于 javascript 另一方面(例如计算或绘制数据)。不过要注意 phone 个数字!

我喜欢@ian-d-miller 将数据转换为键/值样式格式的解决方案,但我一直 运行 他的代码存在问题。

以下是对我有用的方法:

function convert_CSV_to_JSON($csv_data){

    // convert csv data to an array
    $data = array_map("str_getcsv", explode("\n", $csv_data));

    // use the first row as column headers
    $columns = $data[0];

    // create array to hold our converted data
    $json = [];

    // iterate through each row in the data
    foreach ($data as $row_index => $row_data) {

        // skip the first row, since it's the headers
        if($row_index === 0) continue;

        // make sure we establish each new row as an array
        $json[$row_index] = [];

        // iterate through each column in the row
        foreach ($row_data as $column_index => $column_value) {

            // get the key for each entry
            $label = $columns[$column_index];

            // add this column's value to this row's index / column's key
            $json[$row_index][$label] = $column_value;       
        }
    }

    // bam
    return $json;
}

用法:

// as is
$json = convert_CSV_to_JSON($csv);

// encoded
$json = json_encode($json);

这个问题现在已经很老了,但希望这对某人有所帮助,因为它似乎是我找到的最简单的例子,而且我知道这是开发人员作为初学者可能需要做的一件很常见的事情,而且很多答案掩盖了魔法。

$file = storage_path('app/public/waitlist_users_test.csv'); //--> laravel helper, but you can use any path here

function csv_to_json($file)
  {
    // file() loads each row as an array value, then array map uses the 'str_getcsv' callback to 
      $csv = array_map('str_getcsv', file($file)); 

    //  array_walk - "walks" through each item of the array and applies the call back function. the & in "&row" means that alterations to $row actually change the original $csv array, rather than treating it as immutable (*sort of immutable...)
      array_walk($csv, function(&$row) use ($csv) {
     
        // array_combine takes the header row ($csv[0]) and uses it as array keys for each column in the row
        $row = array_combine($csv[0], $row); 
      });
      
    array_shift($csv); # removes now very redundant column header --> contains {'col_1':'col_1', 'col_2':'col_2'...}
    $json = json_encode($csv);

    return $json;
  }

这些函数有很多神奇之处 accept callback functions, that didn't seem to be explained thoroughly above. I'm self taught and have been programming for years, and find that it's often just glossed over without detailing how callbacks work, so I'll dive in just a little bit for the array_map('str_getcsv', file($file)) function - ,它将采用调用函数(在本例中 array_map), 并将其传递给回调函数而无需显式传递变量 - 一旦掌握了它就会非常有用,但我发现它经常没有被彻底解释这让初学者无法理解为什么有效,只是有效.

我已经链接了上面的大部分内容,但这里有更多信息: str-getcsv do? Array Walk Array Map Callables/Callbacks

如@MoonCactus 所述,file() 函数一次仅加载 1 行,这有助于节省大型 .csv 文件的内存使用量。

此外,一些其他帖子引用了使用 explode - why not use explode() instead of str_getcsv() to parse rows? Because explode() would not treat possible enclosured parts of string or escaped characters correctly.

希望有人觉得这有用!

public function CsvToJson($fileContent){
    //Convert CSV To Json and Return
    $all_rows = array();
    $newhead =array();
    //Extract csv data to array on \n
    $array = explode("\n",$fileContent);
    //Extract csv header to array on 0 Index
    $header = explode(",",$array[0]);
    //Remove Header Row From Main Data Array
    array_shift($array);
    //Extract All Arrays To Saperate Orders
    foreach($array as $arr){
       $sliced = explode(",",$arr);
       array_push($all_rows,$sliced); 
    }
    //Extract All Orders Element To Saperate Array Item
    foreach($all_rows as $row){
       $sliced = explode(",",$arr);
       array_push($all_rows,$sliced); 
    }
    //Remove \r From Header Elements
    foreach($header as $key=>$value){
       $sliced = str_replace ("\r", "", $value);
       array_push($newhead,$sliced); 
    }

    //COMBINE Header as KEY And Row Element As Value
    $arrrr = array();
    foreach($all_rows as $row) {
        //Remove Last Element of ROW if it is \r (Break given in css file for next row)
        $count= count($row);
        if ($row[$count-1] == "\r") {
           array_splice($row, count($row) - 1, 1);
        }
        //CHECK IF HADER COUNT == ROW COUNT
        if (count($header) == count($row)) {
            array_push($arrrr,array_combine($newhead,$row));
        }
        
    } 
    //CONVERT ARRAY TO JSON
    $json = json_encode($arrrr);
    //Remove backslasesh from json key and and value to remove \r
    $clean = stripslashes($json);
    //CONVERT ARRAY TO JSON AGAIN FOR EXPORT
    $jsonagain = json_encode($clean);
    return $jsonagain;
}