PHP массив с массивом (2d массив?) В CSV - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь создать CSV из массива с некоторыми данными и другим массивом в нем.

Код:

public function exportCSV()
{
    $user = Auth::user();
    $company = $user->company;
    $dealers = $company->dealers;

    $formatted_dealers = [];

    foreach ($dealers as $dealer) {
        if($dealer->is_deleted == 0){
          array_push($formatted_dealers, $dealer);
        }
    }

    if(count($formatted_dealers) > 0){
        $csvData = array('name,phone,email,is_active,streetname,number,zip,city,special_id,products');
        foreach($formatted_dealers as $dealer){
            $products = [];
            foreach ($dealer->products as $product) {
              array_push($products, $product->slug);
            }
            $products = json_encode($products);
            $csvData[] = $dealer->name . ',' . $dealer->phone . ',' . $dealer->email . ',' . $dealer->is_active . ',' . $dealer->address->streetname . ',' . $dealer->address->number . ',' . $dealer->address->zip . ',' . $dealer->address->city . ',' . $dealer->special_id . ',' . $products;
        }

        $new_time = date('d-m-Y h:i:s', strtotime('+2 hours'));
        $filename = $new_time . '.csv';
        $file_path = base_path() . '/' . $filename;
        $file = fopen($file_path,'w+');
        foreach ($csvData as $exp_data){
          fputcsv($file, explode(',', $exp_data));
        }
        fclose($file);

        $headers = ['Content-Type' => 'application/csv'];

        return response()->download($file_path, $filename, $headers)->deleteFileAfterSend(true);
    } else {
        return redirect()->route('dealers.index', ['export' => 'error']);
    }
}

Итак, у меня есть некоторые данные, такие как имя дилера, телефон и т. Д., И массив продуктов, которые есть у дилера. Моя мысль заключалась в том, чтобы json_encode массива продуктов и затем добавить к строке, которая передается в массив csvData. Но результат, который я получаю при этом:

name,phone,email,is_active,streetname,number,zip,city,special_id,products
"Some name",11111111,example@example.com,1,xxxx,x,xxxx,xxxxxxxx,96548,"[""nBuGbW""","""qP3DAF""]"
"Another name",22222222,anoter@example.com,0,xxxxxxxx,x,xxxx,xxxxxx,,"[""nBuGbW""","""IRTQBN""]"

продуктов в массиве json слишком много ", и я не могу понять, почему. Есть идеи?

В моей голове должно быть что-то вроде:

name,phone,email,is_active,streetname,number,zip,city,special_id,products
"Some name",11111111,example@example.com,1,xxxx,x,xxxx,xxxxxxxx,96548,["nBuGbW","qP3DAF"]"
"Another name",22222222,anoter@example.com,0,xxxxxxxx,x,xxxx,xxxxxx,,["nBuGbW","IRTQBN"]"

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Это должен быть комментарий, но он немного длинный (проблема, о которой вы спрашивали, как говорит jeroen, заключается в двойном кодировании данных CSV).

Моя мысль заключалась в том, чтобы json_encode массива продуктов и затем добавить к строке

Таким образом, у вас есть желание изобрести собственную систему кодирования, которая подразумевает, что вы управляете кодом, который кодирует и декодирует данные. Но почему вы записываете данные в плоский файл?

Вы отправляетесь в целый мир боли, если используете плоские файлы в качестве базы данных. Есть причина, по которой программисты используют такие вещи, как Oracle, MySQL, MongoDB, Redis ...., по крайней мере, последние 40 лет.

Если, с другой стороны, вы пытаетесь реализовать способ публикации данных в разных экземплярах приложения (который использует правильную БД), то есть много, гораздо более эффективных способов сделать это.

Если вы публикуете данные для использования кем-то другим, вам не следует изобретать свою кодировку.

Это похоже на проблему XY.

0 голосов
/ 01 ноября 2018

Проблема в том, что вы создаете вручную - неверно - csv:

$csvData[] = $dealer->name . ',' . $dealer->phone . ',' . $dealer->email . ',' 
    . $dealer->is_active . ',' . $dealer->address->streetname . ',' . $dealer->address->number . ',' 
    . $dealer->address->zip . ',' . $dealer->address->city . ','
    . $dealer->special_id . ',' . $products;

Ваш $products json также будет содержать запятые, поэтому, когда вы explode() запятые, все ваши данные испорчены, и вы сделали недействительным свой json:

foreach ($csvData as $exp_data) {
    // Here you break your json data
    fputcsv($file, explode(',', $exp_data));
}

Вместо этого вы должны использовать многомерный массив, что делает ненужным взрыв:

$csvData[] = [
    $dealer->name,
    ...
    $products,
];

и:

foreach ($csvData as $exp_data) {
    fputcsv($file, $exp_data);
}

Обратите внимание, что если сделать его действительным csv, это приведет к экранированию, например, двойных кавычек. Так что это все равно будет выглядеть странно: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...