需要csv文件上传才能获取所有行但当前正在获取第一行

时间:2017-03-23 06:44:25

标签: php laravel file-upload import-csv

这是我控制器中上传功能的代码。手头的问题是,当我将csv文件上传到我的数据库时,我只获取(获取)文件的第一行,其余的行被省略我需要能够从文件中获取所有行。请尽可能协助你...提前致谢

public function upload(Request $request)
{   
    //get file
    //$allowed =  array('csv');
    $upload=$request->file('upload');
    //$extension = File::extension($upload);
    $filePath=$upload->getRealPath();


    //open and read
    $file=fopen($filePath,'r');
    $header= fgetcsv($file);
    $escapedHeader=[];

    //validate
    foreach ($header as $key => $value) {

        $lheader= strtolower($value);
        $escapedItem=preg_replace('/[^a-z]/', '', $lheader);

        array_push($escapedHeader, $escapedItem);

    }
    //looping throught other columns

    while ($columns=fgetcsv($file)) {

        if ($columns[0]=="") 
        {
            continue;
        }

        $data= array_combine($escapedHeader, $columns);
        dd($data);
        //setting type

        foreach ($data as $key => $value) {
            $value=($key=="phone" || $key=="nationalid" || $key=="staffsalary")?(integer)$value:(string)$value;
        }

        //table update
        $firstname=$data['firstname'];
        $lastname=$data['lastname'];
        $email=$data['email'];
        $phone=$data['phone'];
        $nationalid=$data['nationalid'];
        $staffid=$data['staffid'];
        $stafftitle=$data['stafftitle'];
        $staffsalary=$data['staffsalary'];


        $employees= Employees::firstOrNew(['phone'=>$phone,'nationalid'=>$nationalid]);
        $employees->firstname=$firstname;
        $employees->lastname=$lastname;
        $employees->email=$email;
        $employees->staff_id=$staffid;
        $employees->staff_title=$stafftitle;
        $employees->staff_salary=$staffsalary;
        $employees->employer_phone = Auth::user()->phone;
        $employees->save();

        return redirect()->route('home');

}
}

2 个答案:

答案 0 :(得分:0)

您遇到此问题的主要原因是return redirect()->route('home');位于您的while循环中。只需将它移动到外面它就可以正常工作。

此外,这只是一个FYI,但您可以使用Collections来清理控制器,但是:

public function upload(Request $request)
{
    $upload = $request->file('upload');

    $csv = collect(array_map('str_getcsv', file($upload->getRealPath())));

    $keys = array_map(function ($item) {
        return preg_replace('/[^a-z]/', '', strtolower($item));
    }, $csv->shift());

    $csv
        ->map(function ($row) use ($keys) {
            return array_combine($keys, $row);
        })
        ->reject(function ($row) {
            return empty(array_first($row));
        })
        ->each(function ($row) {

            $row = array_map(function ($value, $key) {
                return in_array($key, ['phone', 'nationalid', 'staffsalary']) ? (integer)$value : (string)$value;
            }, $row);

            $employees = Employees::firstOrNew(['phone' => $row['phone'], 'nationalid' => $row['nationalid']]);
            $employees->firstname = $row['firstname'];
            $employees->lastname = $row['lastname'];
            $employees->email = $row['email'];
            $employees->staff_id = $row['staffid'];
            $employees->staff_title = $row['stafftitle'];
            $employees->staff_salary = $row['staffsalary'];
            $employees->employer_phone = Auth::user()->phone;
            $employees->save();
        });

    return redirect()->route('home');
}

显然,你不必使用上面的代码,我只是想我会告诉你另一种写代码的方式。

我不确定if ($columns[0]=="")是什么,但我已经使用reject()方法添加了。

希望这有帮助!

答案 1 :(得分:0)

您的问题是针对不同操作系统的不同分界线。使用这种结构可以更好:

    // take care of all possible newline-encodings in input file
    $NEWLINE_RE = '/(\r\n)|\r|\n/'; 

    $csv = preg_replace($NEWLINE_RE,'===BREAK===', $old_csv);
    foreach (explode('===BREAK===', $csv) as $k => $line){
       if(strlen($line) > 0) $lines[] = stripcslashes(trim($line));
    }