PHP: CSV в массив

#php #laravel #csv

#php #laravel #csv

Вопрос:

У меня есть следующий csv

Форматирование CSV

И я хочу преобразовать это как :

 $data = array(
 'firstName[0]' => 'test1',
 'lastName[0]' => 'test1',
 'email[0]' => 'test1@gmail.com'
 'firstName[1]' => 'test2',
 'lastName[1]' => 'test2',
 'email[1]' => 'test2@gmail.com'
 ...
 ...
);
  

Следующий код предоставляет мне вложенный массив, и каждая строка имеет индекс в этом массиве,

 $csvData = file_get_contents('filename.csv');
$lines = explode(PHP_EOL, $csvData);
$array = array();
foreach ($lines as $key => $value) {
    $array[$key] = str_getcsv($value);
}
  

Вывод :

Вывод

что в моем случае неправильно, как я смогу этого добиться?

Комментарии:

1. Выполните итерацию вашего массива и создайте новый.

2. Для доводчиков — OP необходим формат массива, который отличается от one, get by str_getcsv и подобных.

3. Я думаю, что ваше понимание структуры массива неверно. Чтобы получить данные из нужного вам массива, вам придется использовать $data['firstName[0]'] . Чтобы получить данные как $data['firstName'][0] , вам нужно было бы иметь их как $data = array( 'firstName' => array( 0=>'test1')); .

4. @u_mulder В принципе, оператору нужно написать некоторый код, а не надеяться, что затирание нескольких встроенных функций может сделать все это за них

5. Вам следует взглянуть на класс Collection в Laravel, который может помочь вам преобразовать ваши данные

Ответ №1:

Я надеюсь, что это поможет вам

 public function importCsv()
{
    $file = public_path('upload/test.csv');

    $customerArr = $this->csvToArray($file);

    for ($i = 0; $i < count($customerArr); $i   )
    {
    //   $customerArr[$i];
       //get data and insert or you ca use
    }

     print_r($customerArr);

}


function csvToArray($filename = '', $delimiter = ',')
{
    if (!file_exists($filename) || !is_readable($filename))
        return false;

    $header = null;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== false)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== false)
        {
            if (!$header)
                $header = $row;
            else
                $data[] = array_combine($header, $row);
        }
        fclose($handle);
    }

    return $data;
}
  

Ответ №2:

 <?php
$csv = array_map('str_getcsv', file('filename.csv'));

for ($j = 1; $j < count($csv); $j  ) {
    for ($i = 0; $i < count($csv[0]); $i  ) {
        $myArray[$csv[0][$i].$j] = $csv[$j][$i];
    }
}

print_r($myArray);
  

Не самое элегантное решение, но оно сработает для вас. Я использовал for циклы, чтобы мне было проще использовать их счетчики. Выходной результат таков :

 Array
(
    [firstName1] => test1
    [lastName1] => Test1
    [email1] => test1@gmail.com
    [firstName2] => test2
    [lastName2] => Test2
    [email2] => test2@gmail.com
)
  

И мой csv-файл выглядел следующим образом:

 firstName,lastName,email
test1,Test1,test1@gmail.com
test2,Test2,test2@gmail.com
  

Первый цикл запускает счетчик с позиции 1, поэтому я избегаю заголовков и буду выполнять цикл вокруг основного массива csv.

Вложенный цикл будет проходить через каждый из вложенных массивов и на основе первого, который содержит информацию заголовка, объединит новые ключевые поля и создаст ваш новый массив.

Если вы хотите, чтобы это было точно как в вашем примере, со скобками и счетчиком, начинающимся с 0 для ключевого поля, тогда вы можете просто:

 <?php
$csv = array_map('str_getcsv', file('filename.csv'));

for ($j = 1; $j < count($csv); $j  ) {
    for ($i = 0; $i < count($csv[0]); $i  ) {
        $counter = $j-1;
        $myArray[$csv[0][$i].'['.$counter.']'] = $csv[$j][$i];
    }
}

print_r($myArray);
  

Который выведет для вас массив, точно такой, как вы просили в своем вопросе:

 Array
(
    [firstName[0]] => test1
    [lastName[0]] => Test1
    [email[0]] => test1@gmail.com
    [firstName[1]] => test2
    [lastName[1]] => Test2
    [email[1]] => test2@gmail.com
)