В каждом цикле сохраняется только первый индекс многомерного массива | Laravel

#php #arrays #laravel #laravel-excel

#php #массивы #laravel #laravel-excel

Вопрос:

Я пытаюсь сохранить значения многомерного массива в отдельные строки и сохранить их в базе данных. У меня есть следующий массив: данные моего ответа:

 [
  {
        "name": "bla bla",
        "creator": "bla bla",
        "cost": 200
    }, {
        "name": "bla bla",
        "creator": "bla bla",
        "cost": 200
    },
    {
        "name": "bla bla",
        "creator": "bla bla",
        "cost": 200
     }
  ]
  

Я пробовал одиночные циклы foreach (как показано ниже), этот код в настоящее время работает, но принимает (сохраняет) только первый индекс. У меня почти 10 КБ данных. Мне нужно, чтобы он возвращал результаты для каждого значения массива.

 public function fileImport(Request $request) 
{   
    set_time_limit(6000);
    $array = (new DrugsImport)->toArray($request->file('file'));
    $i = 0;
    foreach ($array as $item) {
        $drugs = new Drug;
        $drugs->user_id = 1;
        $drugs->name = $item[$i]['name'];
        $drugs->cost = $item[$i]['cost'];
        $drugs->save();
        //$name = utf8_decode($item[$i]['naimenovaniya']);
        // $name = $item[$i]['naimenovaniya'];
        // iconv("Windows-1251", "UTF-8", $name);
        $i  ;
    }
    return response()->json($drugs);

   //Excel::import(new DrugsImport, $request->file('file')->store('temp'));
   //return back();
}
  

В настоящее время этот код хранит только первый элемент [0]. Остальные значения не сохраняются. Я также пробовал использовать несколько других способов, но во всех сохраненных первых элементах.
Я тоже пробовал так:

     foreach ($array as $key => $value) {
    if (is_array($value)) {
        ......
    }
}
  

Я не могу найти, где я ошибаюсь. Кто-нибудь может помочь?
Спасибо!

ОТРЕДАКТИРОВАНО, если я запускаю с помощью var_dump($array) :

     array(1) {
        [0] => array(2897) {
                [0] => array(3) {
                    ["name"] => string(36)
                    "bla bla bla" ["cost"] => int(200)
                } [1] => array(3) {
                     ["name"] => string(36)
                    "bla bla bla" ["cost"] => int(200)
                } [2] => array(3) {
                     ["name"] => string(36)
                    "bla bla bla" ["cost"] => int(200)
                } [3] => array(3) {
                     ["name"] => string(36)
                    "bla bla bla" ["cost"] => int(200)
                }
        ....
  

ОБНОВЛЕНО
Мой файл DrugsImport:

     class DrugsImport implements ToModel, WithHeadingRow
{
    use Importable;

    /**
    * @param array $row
    *
    * @return IlluminateDatabaseEloquentModel|null
    */
    public function model(array $row)
    {
        return new Drug([
            'name '     => $row[0],
            'cost'    => $row[1]
        ]);
    }

}
  

если я дамп $array, он возвращает вот так:

 array:1 [▼
0 => array:2897 [▼
0 => array:3 [ …3]
1 => array:3 [ …3]
2 => array:3 [ …3]
3 => array:3 [ …3]
4 => array:3 [ …3]
....
  

Извините, если это повторяющийся вопрос, но ни один из них не сработал…

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

1. Если $array это то, что вы опубликовали первым, то $item[$i]['name'] следует выдать предупреждение о неопределенном индексе. $item будет подмассивом, поэтому он должен быть только $item['name'] . $i Вообще не нужен.

2. У вас также есть опечатка: ['cose'] должно быть ['cost']

3. Нет, если я использую $index['name'] , он возвращает ошибку Undefined index: name .

4. что вы увидите, если вы сбросите массив перед циклом? dump($array)

5. Тогда массив не будет похож на тот, который вы опубликовали. Вот демонстрация: 3v4l.org/LlTXC

Ответ №1:

вы можете попробовать так. сообщите нам, если вы получите ошибку

 // controller fileImport     
public function fileImport(Request $request) 
{   
   $drug = new DrugsImport;
   Excel::import($drug, $request->file('file'));
   return $drug->drugResu<
} 

// Drug Import 
use MaatwebsiteExcelConcernsWithHeadingRow;
use MaatwebsiteExcelConcernsToCollection;
class DrugsImport implements ToCollection, WithHeadingRow
{
      public $drugResult;
      public function collection(Collection $rows)
      {
          $this->drugResult = $rows;
      }
} 
  

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

1. Спасибо, этот способ работает, но мне нужен другой способ. Мне нужно выполнить необходимые действия со значениями внутри массива (разделить, обрезать и т.д.). Это должен быть выполнен импорт в контроллере.

2. что вы имеете в виду под необходимыми действиями? я не могу понять

3. Извините, мой английский не очень хорош, я должен удалить некоторые значения в массиве, мне нужно отредактировать значения, поэтому это было необходимо в контроллере.

Ответ №2:

Итак, есть несколько проблем с вашим кодом.

Формат

Ваш массив — это массив, содержащий один массив, который содержит несколько массивов, поэтому, если вы делаете только:

 foreach ($array as $item)
  

он будет повторять его только один раз (поскольку $array содержит только один массив), поэтому вы получили только первый.

Если вы делаете

 foreach ($array[0] as $item)
  

и используйте $item['name'] , он будет перебирать все элементы.

Почему он возвращает только последний?

Это потому, что вы перезаписываете $drugs переменную на каждой итерации.

Если вы хотите вернуть их все, вместо этого добавьте их в массив. Это должно сделать это:

 // Define the array where we will add the drugs so we can return them all
$listOfDrugs = [];

foreach ($array[0] as $item) {
    $drug = new Drug;
    $drug->user_id = 1;
    $drug->name = $item['name'];
    $drug->cost = $item['cost'];
    $drug->save();       

    // Add the new drug to the array so it can be returned after the loop
    $listOfDrugs[] = $drug;
}

// Now return the array with all the drugs
return response()->json($listOfDrugs);