Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将CSV文件导入Laravel控制器并将数据插入两个表_Php_Laravel_Csv_Laravel 5 - Fatal编程技术网

Php 将CSV文件导入Laravel控制器并将数据插入两个表

Php 将CSV文件导入Laravel控制器并将数据插入两个表,php,laravel,csv,laravel-5,Php,Laravel,Csv,Laravel 5,所以我完全是拉雷维尔的不速之客,我正在尝试一些东西。我想将CSV文件导入到两个表中,我有一个名为lists的表,该表将获得列表名称和客户机id 然后我有一个名为customers的表,它将获得姓名、姓氏、联系电话以及客户id和列表id 我想要实现的是导入一个CSV文件,该文件将采用文件名并将其存储在列表表中,然后通过CSV文件创建一个数组,并使用列表和客户端id将数据导入到customers表中 我已经完成了第一部分,并且它正确地插入到列表表中,现在如何从存储/文档中的CSV创建一个数组,然后将

所以我完全是拉雷维尔的不速之客,我正在尝试一些东西。我想将CSV文件导入到两个表中,我有一个名为lists的表,该表将获得列表名称和
客户机id

然后我有一个名为customers的表,它将获得姓名、姓氏、联系电话以及
客户id
列表id

我想要实现的是导入一个CSV文件,该文件将采用文件名并将其存储在列表表中,然后通过CSV文件创建一个数组,并使用列表和客户端id将数据导入到customers表中

我已经完成了第一部分,并且它正确地插入到列表表中,现在如何从存储/文档中的CSV创建一个数组,然后将其插入到客户表中

namespace App\Http\Controllers;

use Input;
use DB;
use Illuminate\Http\Request;
use App\Http\Requests\ListsRequest;
use App\Lists;
use App\Clients;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class ListsController extends Controller {

    public function index()
    {
        // $list_items = Lists::all();
        $clients = Clients::all();

        return view('lists.show', compact('clients'));
    }

    public function store(Requests\ListsRequest $request)
    {
        $input = $request->input();
        Lists::create($input);

        if (Input::hasFile('name'))
        {

            $file = Input::file('name');
            $name = time() . '-' . $file->getClientOriginalName();

            $path = storage_path('documents');

            $file->move($path, $name);

            // All works up to here
            // All I need now is to create an array
            // from the CSV and insert into the customers database
        }
    }
}
我选择使用我已经接受的答案,但我也使用了另一个答案,并让它像这样工作

public function store(Requests\ListsRequest $request)
{
    $input = $request->input();
    $client_id = $request->input('client_id');

    if (Input::hasFile('name'))
    {
        $file = Input::file('name');
        $name = time() . '-' . $file->getClientOriginalName();
        $path = storage_path('documents');

        Lists::create(['client_id' => $client_id, 'name' => $name]);

        $reader = Reader::createFromPath($file->getRealPath());
        // Create a customer from each row in the CSV file
        $headers = array();

        foreach ($reader as $index => $row)
        {
            if ($index === 0)
            {
                $headers = $row;
            } else
            {
                $data = array_combine($headers, $row);
                Customers::create($data);
            }
        }

        $file->move($path, $name);

        return view('clients');
    }
}
store()
方法中,在
列表
表中创建记录,然后迭代CSV文件的内容,并将数据插入
客户
表中。为此,您应该在客户和列表之间创建一个链接。您最好使用类似的方法来读取此类文件:

公共函数存储(addCustomerRequest$request)
{
//获取上传的CSV文件
$file=$request->file('csv');
//创建列表名
$name=time().'-'.$file->getClientOriginalName();
//在数据库中创建列表记录
$list=list::create(['name'=>$name]);
//创建一个CSV阅读器实例
$reader=reader::createFromFileObject($file->openFile());
//从CSV文件中的每一行创建一个客户
foreach($reader as$index=>$row){
$list->customers()->创建($row);
}
//使用成功消息重定向回您需要的位置
}

读取CSV文件并将其导入Laravel中的数据库有3个步骤

  • 读取CSV文件
  • 将其转换为数组
  • 最后在数据库中创建记录
  • 在开始之前,我已经创建了一个示例
    test.csv
    文件,并将其放在我的公用文件夹中的文件夹下:

    name,email,password
    user1,email1@email.com,pasxxxxxxxxxword
    user2,email2@email.com,pasxxxxxxxxxword
    user3,email3@email.com,pasxxxxxxxxxword
    
    步骤1和2;我创建了一个名为
    csvToArray
    的助手函数,现在我只是将它放在控制器中(此函数受此启发),它只读取CSV文件并将其转换为数组:

    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;
    }
    
    步骤3;这是我的最后一步,读取数组并将其插入数据库:

    public function importCsv()
    {
        $file = public_path('file/test.csv');
    
        $customerArr = $this->csvToArray($file);
    
        for ($i = 0; $i < count($customerArr); $i ++)
        {
            User::firstOrCreate($customerArr[$i]);
        }
    
        return 'Jobi done or what ever';    
    }
    
    public function importsv()
    {
    $file=public_路径('file/test.csv');
    $customerArr=$this->csvToArray($file);
    对于($i=0;$i
    注意:此解决方案假定您的Laravel项目中有一个模型,并且数据库中有适当的表

    如果您使用
    dd($customerArr)
    您将得到这个

    @maytham由maytham提出的解决方案将很有效。然而,如果你试图处理大数据,它将有一个巨大的问题。即使您执行了1000行,也会产生问题,因为它将分别生成1000条insert语句。我将编辑他的第三个方法并添加我自己的输入

    public function importCsv()
    {
        $file = public_path('file/test.csv');
    
        $customerArr = $this->csvToArray($file);
        $data = [];
        for ($i = 0; $i < count($customerArr); $i ++)
        {
            $data[] = [
                'column_name1' => 'value',
                'column_name2' => 'value2',
                .. so..on..and..on
            ];
            //User::firstOrCreate($customerArr[$i]);
        }
        DB::table('table_name')->insert($data);
        return 'Jobi done or what ever';    
    }
    
    public function importsv()
    {
    $file=public_路径('file/test.csv');
    $customerArr=$this->csvToArray($file);
    $data=[];
    对于($i=0;$i'值',
    'column_name2'=>'value2',
    …那么..继续..继续
    ];
    //用户::firstOrCreate($customerArr[$i]);
    }
    DB::table('table_name')->insert($data);
    返回“Jobi done或其他任何内容”;
    }
    
    这将调用数据库一次,以插入任意多的行。不管是1000、100000还是别的什么。
    然而,如果你有一个巨大的csv,这将是一个问题,因为你将被要求插入块。与PostgreSQL一样,我注意到在一条语句中最多可以插入65000行。也许我的数字错了,但每个数据库都有一个限制,你需要寻找它。

    首先看看这个,你不能像你那样直接插入数据库,如果链接没有提供帮助,让我知道,我现在正在尝试:)谢谢,会让你知道它是如何在一个fewOkay中进行的,所以我尝试了上面编辑的问题中看到的内容,但现在我只是得到了一个空白屏幕,即使我只是返回“hello”,我在哪里有你能帮我解释一下我添加的区域的逻辑吗?重要的是逐步解决问题,所以如果它不返回hello,这意味着它没有得到文件或者你的if语句返回false,为了好玩,试着在if语句之前写dd($input),看看你的控制器是否有生命,并找出$input是否包含你所期望的东西。我使用@maytham-ɯɥıλɐɯ的函数来实现这一点,但我也尝试了你的答案,看看如何做到这一点,我正在编辑我的问题让你看。我认为这是一个很好的方法。但是对于一个大的CSV,比如100000行,会发生什么呢?该阵列将有一个大的大小,我可能有问题的内存ram。在这种情况下,标题取决于您的数据模型中提到的说明。在我的情况下,它是用户模型,它包含名称,电子邮件密码。你自己做,试试看。如果我误解了你的意思,请告诉我。@maytham-ɐɥʇʎɯ你能告诉我,上传csv文件后你是如何破解密码的吗?@ToxifiedHashkey我已经停止与laravel合作几年了。但是bcrypt函数你可以在谷歌上搜索它并找到一个函数来bcrypt密码。但是$customerArr[$i]是您导入的每个对象,您可以在概念上做一些事情,比如不进行测试和验证$customerArr[$i]->password=bcryptFunction($customerArr[$i]->password)这将用