使用 Laravel 将经过验证的制表符分隔文件导入 MySQL
Import validated tab delimited file to MySQL with Laravel
我正在尝试上传制表符分隔的文本文件。
问题可能是列并不总是以相同的顺序排列。
一旦上传了喜欢的ID,请执行以下步骤:
- 验证列名。如果验证通过 -> 2
- 逐行读取文件(最好跳过列名)并验证一些值。如果一行通过验证 -> 3.
- 创建模型 object 并将其存储在数组中以供以后批量插入。
- 对文件中的所有行重复。
- 完成所有行并验证所有内容后,批量插入所有 objects。
到目前为止,我已经完成了上传部分并尝试了一些不同的解决方案。但我现在几乎被困住了。
我将从控制器粘贴我的代码(请记住文件中有 40 列我刚刚编写了其中的一些):
public function store()
{
$file = Input::file('file');
$rules = array(
'file' => 'required|mimes:txt'
);
$validator = Validator::make(array('file'=> $file), $rules);
if($validator->passes()){
foreach(file($file) as $row) {
$row = explode("\t", $row);
$validator = Validator::make(array(
'X'=> $row[0],
'Y'=> $row[1],
'year'=> $row[2],
'provnr'=> $row[3],
'id'=> $row[4]
), Sample::$insertRules);
if($validator->passes()){
$sample = New Sample;
$sample->X = $row[0];
$sample->Y = $row[1];
$sample->year = $row[2];
$sample->provnr = $row[3];
$sample->costumer_id = $row[4];
$sample->save();
} else {
Session::flash('notice', 'Something is wrong!');
Session::flash('sample', $row[3]);
return Redirect::to('import');
}
}
exit;
Session::flash('success', 'Upload successfully');
return Redirect::to('import');
}
else {
// redirect back with errors.
return Redirect::to('import')->withInput()->withErrors($validator);
}
}
这很好用(还没有批量插入,稍后我会倾向于),但我不是很喜欢它,我认为有更好的解决方案。
别介意验证,它还没有真正完成。
如果我 print_r 您可以在该文本下方找到的所有行,我最终会得到什么。
现在有点困难,因为列名是第一个数组。沿线的某个地方 id 喜欢将其删除。因为它不会通过其他行验证。
Array ( [0] => x [1] => y [2] => År [3] => Provnr )
Array ( [0] => 1315903.24 [1] => 6213877.72 [2] => 2014 [3] => 223 )
Array ( [0] => 1315819.62 [1] => 6213937.42 [2] => 2014 [3] => 224 )
所以,我很想知道你们对此的想法。你有什么想法吗?
我认为以某种方式将数组转换为 objects 会更好。所以我得到了类似数据库结果的东西。我只是不知道怎么办。
我希望能够在我的 foreach 循环中编写 $row['X'] 。我认为那会好得多。
有什么方法可以做到这一点吗?列名将是每个 object 的标识。
非常感谢您的帮助!
编辑:
所以现在问题出在我的文件的特殊字符上。
我根据 Bogdan 的评论进行了一些编辑。
我已经包含了完整的 $columnMap
代码现在看起来像这样:
$file = Input::file('file');
$rules = array(
'file' => 'required|mimes:txt'
);
$validator = Validator::make(array('file'=> $file), $rules);
if($validator->passes()){
$columns = [];
$columnMap = [
'x' => 'X',
'y' => 'Y',
'Ar' => 'Year',
'Provnr' => 'Provnr',
'Markning' => 'costumer_id',
'pH' => 'pH',
'P_AL' => 'P_AL',
'P_HCl' => 'P_HCl',
'K_AL' => 'K_AL',
'K_HCl' => 'K_HCl',
'Mg_AL' => 'Mg_AL',
'Cu_HCl' => 'Cu_HCl',
'K_Mg_kvot' => 'K_Mg_kvot',
'Bor' => 'Bor',
'Ca_AL' => 'Ca_AL',
'fe' => 'fe',
'al' => 'al',
'Mullhalt' => 'Mullhalt',
'Total_lerhalt' => 'Total_lerhalt',
'Sand_grovmo' => 'Sand_grovmo',
'Volymvikt' => 'Volymvikt',
'T_varde' => 'T_värde',
'S_varde' => 'S_värde',
'Basmattnadsgrad' => 'Basmättnadsgrad',
'Cd_HNO3' => 'Cd_HNO3',
'Kalkbehov' => 'Kalkbehov',
'Jordart' => 'Jordart',
'Fin_lerhalt' => 'Fin_lerhalt',
'Zn' => 'Zn',
'Cu' => 'Cu',
'Cr' => 'Cr',
'Ni' => 'Ni',
'Pb' => 'Pb',
'Hg' => 'Hg',
'Mineralkvave_Kg_N_ha' => 'Mineralkväve_Kg_N_ha',
'Mineralkvave_NO3_N' => 'Mineralkväve_NO3_N',
'Mineralkvave_NH4_N' => 'Mineralkväve_NH4_N',
'Mineralkvave_djup' => 'Mineralkväve_djup',
'Cystnematoder_potatis' => 'Cystnematoder_potatis',
'Cystnematoder_betor' => 'Cystnematoder_betor',
'Cystnematoder_spannmal' => 'Cystnematoder_spannmål',
'Ovrigt' => 'Övrigt'
];
foreach(file($file) as $i => $row)
{
$row = explode("\t", $row);
if($i == 0)
{
$columns = $row;
array_walk($columns, function (&$item)
{
$item = str_replace(
['ä', 'å', 'ö', 'Ä', 'Å', 'Ö'],
['a', 'a', 'o', 'A', 'A', 'O'],
utf8_encode($item)
);
});
continue;
}
$_row = array();
array_walk($row, function ($value, $index) use (&$_row, $columns, $columnMap)
{
$_row[$columnMap[$columns[$index]]] = $value; //*The issue is here.*
});
$row = $_row;
$validator = Validator::make($row, Sample::$insertRules);
if($validator->passes()){
$sample = New Sample;
foreach ($row as $property => $value)
$sample->{$property} = $value;
$sample->save();
} else
{
Session::flash('notice', 'Something is wrong!');
return Redirect::to('import');
}
}
我必须 utf8_encode 文件的 header ,否则它不会工作。这可能是文本文件的问题吗?
在需要对具有值的行执行 array_walk 之前,它似乎一直在工作。
然后我得到这个错误:Undefined index: Ovrigt
如果我 var_dump $columns 它看起来像这样:
array(42) { [0]=> 字符串(1) "x" [1]=> 字符串(1) "y" [2]=> 字符串( 2) "Ar" [3]=> 字符串(6) "Provnr" [4]=> 字符串(8) "Markning" [5]=> 字符串(2) "pH" [ 6]=> 字符串(4) "P_AL" [7]=> 字符串(5) "P_HCl" [8]=> 字符串(4) "K_AL" [9]=> 字符串(5) "K_HCl" [10]=> 字符串(5) "Mg_AL" [11]=> 字符串(6) "Cu_HCl" [12]=> 字符串(9) "K_Mg_kvot" [13] => 字符串(3) "Bor" [14]=> 字符串(5) "Ca_AL" [15]=> 字符串(2) "fe" [16]=> 字符串(2) "al" [17]=> 字符串(8) "Mullhalt" [18]=> 字符串(13) "Total_lerhalt" [19]=> 字符串(11) "Sand_grovmo" [20]=>字符串(9) "Volymvikt" [21]=> 字符串(7) "T_varde" [22]=> 字符串(7) "S_varde" [23]=> 字符串(15) "Basmattnadsgrad" [24]=> 字符串(7) "Cd_HNO3" [25]=> 字符串(9) "Kalkbehov" [26]=> 字符串(7) "Jordart" [27]=> 字符串( 11) "Fin_lerhalt" [28]=> 字符串(2) "Zn" [29]=> 字符串(2) "Cu" [30]=> 字符串(2) "Cr" [ 31]=> 字符串(2) "Ni" [32]=> 字符串(2) "Pb" [33]=> 字符串(2) "Hg" [34]=> 字符串(20) "Mineralkvave_Kg_N_ha" [35]=> 字符串(18) "Mineralkvave_NO3_N" [36]=> 字符串(18) "Mineralkvave_NH4_N" [37]=> 字符串(17) "Mineralkvave_djup" [38] => 字符串(21) "Cystnematoder_potatis" [39]=> 字符串(19) "Cystnematoder_betor" [40]=> 字符串(22) "Cystnematoder_spannmal" [41]=> 字符串(8) "Ovrigt " }
如果var_dump $columnMap它看起来像这样:
array(42) { ["x"]=> 字符串(1) "X" ["y"]=> 字符串(1) "Y" ["Ar"]=> 字符串(4) "Year" ["Provnr"]=> 字符串(6) "Provnr" ["Markning"]=> 字符串(11) "costumer_id" ["pH"]=> 字符串(2) "pH" ["P_AL"]=> 字符串(4) "P_AL" ["P_HCl"]=>字符串(5) "P_HCl" ["K_AL"]=> 字符串(4) "K_AL" ["K_HCl"]=> 字符串(5) "K_HCl" ["Mg_AL"]=> 字符串(5) "Mg_AL" ["Cu_HCl"]=> 字符串(6) "Cu_HCl" ["K_Mg_kvot"]=> 字符串(9) "K_Mg_kvot" [ "Bor"]=> 字符串(3) "Bor" ["Ca_AL"]=> 字符串(5) "Ca_AL" ["fe"]=> 字符串(2) "fe" ["al"]=> 字符串(2) "al" ["Mullhalt"]=> 字符串(8) "Mullhalt" ["Total_lerhalt"]=> 字符串( 13) "Total_lerhalt" ["Sand_grovmo"]=> 字符串(11) "Sand_grovmo" ["Volymvikt"]=> 字符串(9) "Volymvikt" ["T_varde"] => 字符串(8) "T_värde" ["S_varde"]=> 字符串(8) "S_värde" ["Basmattnadsgrad"]=> 字符串(16) "Basmättnadsgrad" ["Cd_HNO3"]=> 字符串(7) "Cd_HNO3" ["Kalkbehov"]=> 字符串(9) "Kalkbehov" ["Jordart"]=> 字符串(7) "Jordart" ["Fin_lerhalt"]=> 字符串(11) "Fin_lerhalt" ["Zn"]=> 字符串(2) "Zn" ["Cu"]=> 字符串(2) "Cu" ["Cr"]=> 字符串(2) "Cr" ["Ni"]=> 字符串(2) "Ni" ["Pb"]=>字符串(2) "Pb" ["Hg"]=> 字符串( 2) "Hg" ["Mineralkvave_Kg_N_ha"]=> 字符串(21) "Mineralkväve_Kg_N_ha" ["Mineralkvave_NO3_N"]=> 字符串(19) "Mineralkväve_NO3_N" ["Mineralkvave_NH4_N"] => 字符串(19) "Mineralkväve_NH4_N" ["Mineralkvave_djup"]=> 字符串(18) "Mineralkväve_djup" ["Cystnematoder_potatis"]=> 字符串(21) "Cystnematoder_potatis" ["Cystnematoder_betor"]=> 字符串(19) "Cystnematoder_betor" ["Cystnematoder_spannmal"]=> 字符串(23) "Cystnematoder_spannmÃ¥l" ["Ovrigt"]=> 字符串(7) "Övrigt " }
如果我 var_dump 第一个 $ 行具有 值 它看起来像这样:
array(42) { [0]=> 字符串(10) "1315903.24" [1]=> 字符串(10) "6213877.72"[2]=> 字符串(4) "2014" [3]=> 字符串(3) "223" [4]=> 字符串(4) "6510" [5]=> 字符串(3) "6.8" [6 ]=> string(4) "10.0" [7]=> string(0) "" [8]=> string(3) "9.5" [9]=> string(0) "" [10]=> string (4) "12.0" [11]=> 字符串(0) "" [12]=> 字符串(3) "0.8" [13]=> 字符串(0) "" [14]=> 字符串(5) " 150.0" [15]=> 字符串(0) "" [16]=> 字符串(0) "" [17]=> 字符串(0) "" [18]=> 字符串(0) "" [19]= > 字符串(0) "" [20]=> 字符串(0) "" [21]=> 字符串(0) "" [22]=> 字符串(0) "" [23]=> 字符串(0) " “ [24]=> 字符串(0) “” [25]=> 字符串(0) “” [26]=> 字符串(0) “” [27]=> 字符串(0) “” [28]=>字符串(0) "" [29]=> 字符串(0) "" [30]=> 字符串(0) "" [31]=> 字符串(0) "" [32]=> 字符串(0) "" [33]=> 字符串(0) "" [34]=> 字符串(0) "" [35]=> 字符串(0) "" [36]=> 字符串(0) "" [37]=> 字符串(0) "" [38]=> 字符串(0) "" [39]=> 字符串(0) "" [40]=> 字符串(0) "" [41]=> 字符串(12) "J038790-14 " }
现在我不知道可能是什么问题。还有什么我可以 post 让你们更好地理解的吗?
由于 "Ovrigt" 是最后一个,它似乎在那个之前工作正常。
奇怪的是,当我 var_dump $columns.. 时,"Ovrigt " 中似乎有一个空白 space。可能是这样吗?
假设文件的第一行总是包含列名,这里有一个快速实现的方法:
// Define the array that will contain the columns names
$columns = [];
foreach($rows as $i => $row)
{
$row = explode("\t", $row);
// For the first row get the get the column names
if ($i == 0)
{
$columns = $row;
continue; // Skip this iteration
}
// Map each column name to every item in the row
$_row = array();
array_walk($row, function ($value, $index) use (&$_row, $columns)
{
$_row[$columns[$index]] = $value;
});
$row = $_row;
// You can now access row items with
// $row['X'], $row['Y'], etc.
...
}
如果您确切知道所有列都将出现在文件中(无论顺序如何),您可以更进一步,将文件中的列名称映射到对应的模型 属性 名称。这将使验证和填充每个模型更加无缝:
// Define the array that will contain the columns names
$columns = [];
// Define the column mapping
// 'column name' => 'model property name'
$columnMap = [
'X' => 'X',
'Y' => 'Y',
'Ar' => 'year',
'Provnr' => 'provnr',
'id' => 'customer_id'
];
foreach($rows as $i => $row)
{
// Assuming the column names are always on the first row
if ($i == 0)
{
$columns = $row;
// Replace Swedish special chars with simple Latin chars
array_walk($columns, function (&$item)
{
$item = str_replace(
['ä', 'å', 'ö', 'Ä', 'Å', 'Ö'],
['a', 'a', 'o', 'A', 'A', 'O'],
trim($item)
);
});
continue; // Skip this iteration
}
// Map each column name to every item in the row
$_row = array();
array_walk($row, function ($value, $index) use (&$_row, $columns, $columnMap)
{
$_row[$columnMap[$columns[$index]]] = $value;
});
$row = $_row;
// Pass the $row directly to the validator because the mapped keys will work
$validator = Validator::make($row, Sample::$insertRules);
if($validator->passes()){
$sample = New Sample;
// You can iterate over the row and assign each value automatically
// because each item key is mapped to a property name
foreach ($row as $property => $value)
$sample->{$property} = $value;
$sample->save();
}
else
{
Session::flash('notice', 'Something is wrong!');
Session::flash('sample', $row[3]);
return Redirect::to('import');
}
}
我正在尝试上传制表符分隔的文本文件。 问题可能是列并不总是以相同的顺序排列。 一旦上传了喜欢的ID,请执行以下步骤:
- 验证列名。如果验证通过 -> 2
- 逐行读取文件(最好跳过列名)并验证一些值。如果一行通过验证 -> 3.
- 创建模型 object 并将其存储在数组中以供以后批量插入。
- 对文件中的所有行重复。
- 完成所有行并验证所有内容后,批量插入所有 objects。
到目前为止,我已经完成了上传部分并尝试了一些不同的解决方案。但我现在几乎被困住了。 我将从控制器粘贴我的代码(请记住文件中有 40 列我刚刚编写了其中的一些):
public function store()
{
$file = Input::file('file');
$rules = array(
'file' => 'required|mimes:txt'
);
$validator = Validator::make(array('file'=> $file), $rules);
if($validator->passes()){
foreach(file($file) as $row) {
$row = explode("\t", $row);
$validator = Validator::make(array(
'X'=> $row[0],
'Y'=> $row[1],
'year'=> $row[2],
'provnr'=> $row[3],
'id'=> $row[4]
), Sample::$insertRules);
if($validator->passes()){
$sample = New Sample;
$sample->X = $row[0];
$sample->Y = $row[1];
$sample->year = $row[2];
$sample->provnr = $row[3];
$sample->costumer_id = $row[4];
$sample->save();
} else {
Session::flash('notice', 'Something is wrong!');
Session::flash('sample', $row[3]);
return Redirect::to('import');
}
}
exit;
Session::flash('success', 'Upload successfully');
return Redirect::to('import');
}
else {
// redirect back with errors.
return Redirect::to('import')->withInput()->withErrors($validator);
}
}
这很好用(还没有批量插入,稍后我会倾向于),但我不是很喜欢它,我认为有更好的解决方案。 别介意验证,它还没有真正完成。
如果我 print_r 您可以在该文本下方找到的所有行,我最终会得到什么。 现在有点困难,因为列名是第一个数组。沿线的某个地方 id 喜欢将其删除。因为它不会通过其他行验证。
Array ( [0] => x [1] => y [2] => År [3] => Provnr )
Array ( [0] => 1315903.24 [1] => 6213877.72 [2] => 2014 [3] => 223 )
Array ( [0] => 1315819.62 [1] => 6213937.42 [2] => 2014 [3] => 224 )
所以,我很想知道你们对此的想法。你有什么想法吗?
我认为以某种方式将数组转换为 objects 会更好。所以我得到了类似数据库结果的东西。我只是不知道怎么办。 我希望能够在我的 foreach 循环中编写 $row['X'] 。我认为那会好得多。 有什么方法可以做到这一点吗?列名将是每个 object 的标识。
非常感谢您的帮助!
编辑:
所以现在问题出在我的文件的特殊字符上。 我根据 Bogdan 的评论进行了一些编辑。 我已经包含了完整的 $columnMap 代码现在看起来像这样:
$file = Input::file('file');
$rules = array(
'file' => 'required|mimes:txt'
);
$validator = Validator::make(array('file'=> $file), $rules);
if($validator->passes()){
$columns = [];
$columnMap = [
'x' => 'X',
'y' => 'Y',
'Ar' => 'Year',
'Provnr' => 'Provnr',
'Markning' => 'costumer_id',
'pH' => 'pH',
'P_AL' => 'P_AL',
'P_HCl' => 'P_HCl',
'K_AL' => 'K_AL',
'K_HCl' => 'K_HCl',
'Mg_AL' => 'Mg_AL',
'Cu_HCl' => 'Cu_HCl',
'K_Mg_kvot' => 'K_Mg_kvot',
'Bor' => 'Bor',
'Ca_AL' => 'Ca_AL',
'fe' => 'fe',
'al' => 'al',
'Mullhalt' => 'Mullhalt',
'Total_lerhalt' => 'Total_lerhalt',
'Sand_grovmo' => 'Sand_grovmo',
'Volymvikt' => 'Volymvikt',
'T_varde' => 'T_värde',
'S_varde' => 'S_värde',
'Basmattnadsgrad' => 'Basmättnadsgrad',
'Cd_HNO3' => 'Cd_HNO3',
'Kalkbehov' => 'Kalkbehov',
'Jordart' => 'Jordart',
'Fin_lerhalt' => 'Fin_lerhalt',
'Zn' => 'Zn',
'Cu' => 'Cu',
'Cr' => 'Cr',
'Ni' => 'Ni',
'Pb' => 'Pb',
'Hg' => 'Hg',
'Mineralkvave_Kg_N_ha' => 'Mineralkväve_Kg_N_ha',
'Mineralkvave_NO3_N' => 'Mineralkväve_NO3_N',
'Mineralkvave_NH4_N' => 'Mineralkväve_NH4_N',
'Mineralkvave_djup' => 'Mineralkväve_djup',
'Cystnematoder_potatis' => 'Cystnematoder_potatis',
'Cystnematoder_betor' => 'Cystnematoder_betor',
'Cystnematoder_spannmal' => 'Cystnematoder_spannmål',
'Ovrigt' => 'Övrigt'
];
foreach(file($file) as $i => $row)
{
$row = explode("\t", $row);
if($i == 0)
{
$columns = $row;
array_walk($columns, function (&$item)
{
$item = str_replace(
['ä', 'å', 'ö', 'Ä', 'Å', 'Ö'],
['a', 'a', 'o', 'A', 'A', 'O'],
utf8_encode($item)
);
});
continue;
}
$_row = array();
array_walk($row, function ($value, $index) use (&$_row, $columns, $columnMap)
{
$_row[$columnMap[$columns[$index]]] = $value; //*The issue is here.*
});
$row = $_row;
$validator = Validator::make($row, Sample::$insertRules);
if($validator->passes()){
$sample = New Sample;
foreach ($row as $property => $value)
$sample->{$property} = $value;
$sample->save();
} else
{
Session::flash('notice', 'Something is wrong!');
return Redirect::to('import');
}
}
我必须 utf8_encode 文件的 header ,否则它不会工作。这可能是文本文件的问题吗? 在需要对具有值的行执行 array_walk 之前,它似乎一直在工作。 然后我得到这个错误:Undefined index: Ovrigt
如果我 var_dump $columns 它看起来像这样:
array(42) { [0]=> 字符串(1) "x" [1]=> 字符串(1) "y" [2]=> 字符串( 2) "Ar" [3]=> 字符串(6) "Provnr" [4]=> 字符串(8) "Markning" [5]=> 字符串(2) "pH" [ 6]=> 字符串(4) "P_AL" [7]=> 字符串(5) "P_HCl" [8]=> 字符串(4) "K_AL" [9]=> 字符串(5) "K_HCl" [10]=> 字符串(5) "Mg_AL" [11]=> 字符串(6) "Cu_HCl" [12]=> 字符串(9) "K_Mg_kvot" [13] => 字符串(3) "Bor" [14]=> 字符串(5) "Ca_AL" [15]=> 字符串(2) "fe" [16]=> 字符串(2) "al" [17]=> 字符串(8) "Mullhalt" [18]=> 字符串(13) "Total_lerhalt" [19]=> 字符串(11) "Sand_grovmo" [20]=>字符串(9) "Volymvikt" [21]=> 字符串(7) "T_varde" [22]=> 字符串(7) "S_varde" [23]=> 字符串(15) "Basmattnadsgrad" [24]=> 字符串(7) "Cd_HNO3" [25]=> 字符串(9) "Kalkbehov" [26]=> 字符串(7) "Jordart" [27]=> 字符串( 11) "Fin_lerhalt" [28]=> 字符串(2) "Zn" [29]=> 字符串(2) "Cu" [30]=> 字符串(2) "Cr" [ 31]=> 字符串(2) "Ni" [32]=> 字符串(2) "Pb" [33]=> 字符串(2) "Hg" [34]=> 字符串(20) "Mineralkvave_Kg_N_ha" [35]=> 字符串(18) "Mineralkvave_NO3_N" [36]=> 字符串(18) "Mineralkvave_NH4_N" [37]=> 字符串(17) "Mineralkvave_djup" [38] => 字符串(21) "Cystnematoder_potatis" [39]=> 字符串(19) "Cystnematoder_betor" [40]=> 字符串(22) "Cystnematoder_spannmal" [41]=> 字符串(8) "Ovrigt " }
如果var_dump $columnMap它看起来像这样:
array(42) { ["x"]=> 字符串(1) "X" ["y"]=> 字符串(1) "Y" ["Ar"]=> 字符串(4) "Year" ["Provnr"]=> 字符串(6) "Provnr" ["Markning"]=> 字符串(11) "costumer_id" ["pH"]=> 字符串(2) "pH" ["P_AL"]=> 字符串(4) "P_AL" ["P_HCl"]=>字符串(5) "P_HCl" ["K_AL"]=> 字符串(4) "K_AL" ["K_HCl"]=> 字符串(5) "K_HCl" ["Mg_AL"]=> 字符串(5) "Mg_AL" ["Cu_HCl"]=> 字符串(6) "Cu_HCl" ["K_Mg_kvot"]=> 字符串(9) "K_Mg_kvot" [ "Bor"]=> 字符串(3) "Bor" ["Ca_AL"]=> 字符串(5) "Ca_AL" ["fe"]=> 字符串(2) "fe" ["al"]=> 字符串(2) "al" ["Mullhalt"]=> 字符串(8) "Mullhalt" ["Total_lerhalt"]=> 字符串( 13) "Total_lerhalt" ["Sand_grovmo"]=> 字符串(11) "Sand_grovmo" ["Volymvikt"]=> 字符串(9) "Volymvikt" ["T_varde"] => 字符串(8) "T_värde" ["S_varde"]=> 字符串(8) "S_värde" ["Basmattnadsgrad"]=> 字符串(16) "Basmättnadsgrad" ["Cd_HNO3"]=> 字符串(7) "Cd_HNO3" ["Kalkbehov"]=> 字符串(9) "Kalkbehov" ["Jordart"]=> 字符串(7) "Jordart" ["Fin_lerhalt"]=> 字符串(11) "Fin_lerhalt" ["Zn"]=> 字符串(2) "Zn" ["Cu"]=> 字符串(2) "Cu" ["Cr"]=> 字符串(2) "Cr" ["Ni"]=> 字符串(2) "Ni" ["Pb"]=>字符串(2) "Pb" ["Hg"]=> 字符串( 2) "Hg" ["Mineralkvave_Kg_N_ha"]=> 字符串(21) "Mineralkväve_Kg_N_ha" ["Mineralkvave_NO3_N"]=> 字符串(19) "Mineralkväve_NO3_N" ["Mineralkvave_NH4_N"] => 字符串(19) "Mineralkväve_NH4_N" ["Mineralkvave_djup"]=> 字符串(18) "Mineralkväve_djup" ["Cystnematoder_potatis"]=> 字符串(21) "Cystnematoder_potatis" ["Cystnematoder_betor"]=> 字符串(19) "Cystnematoder_betor" ["Cystnematoder_spannmal"]=> 字符串(23) "Cystnematoder_spannmÃ¥l" ["Ovrigt"]=> 字符串(7) "Övrigt " }
如果我 var_dump 第一个 $ 行具有 值 它看起来像这样:
array(42) { [0]=> 字符串(10) "1315903.24" [1]=> 字符串(10) "6213877.72"[2]=> 字符串(4) "2014" [3]=> 字符串(3) "223" [4]=> 字符串(4) "6510" [5]=> 字符串(3) "6.8" [6 ]=> string(4) "10.0" [7]=> string(0) "" [8]=> string(3) "9.5" [9]=> string(0) "" [10]=> string (4) "12.0" [11]=> 字符串(0) "" [12]=> 字符串(3) "0.8" [13]=> 字符串(0) "" [14]=> 字符串(5) " 150.0" [15]=> 字符串(0) "" [16]=> 字符串(0) "" [17]=> 字符串(0) "" [18]=> 字符串(0) "" [19]= > 字符串(0) "" [20]=> 字符串(0) "" [21]=> 字符串(0) "" [22]=> 字符串(0) "" [23]=> 字符串(0) " “ [24]=> 字符串(0) “” [25]=> 字符串(0) “” [26]=> 字符串(0) “” [27]=> 字符串(0) “” [28]=>字符串(0) "" [29]=> 字符串(0) "" [30]=> 字符串(0) "" [31]=> 字符串(0) "" [32]=> 字符串(0) "" [33]=> 字符串(0) "" [34]=> 字符串(0) "" [35]=> 字符串(0) "" [36]=> 字符串(0) "" [37]=> 字符串(0) "" [38]=> 字符串(0) "" [39]=> 字符串(0) "" [40]=> 字符串(0) "" [41]=> 字符串(12) "J038790-14 " }
现在我不知道可能是什么问题。还有什么我可以 post 让你们更好地理解的吗? 由于 "Ovrigt" 是最后一个,它似乎在那个之前工作正常。 奇怪的是,当我 var_dump $columns.. 时,"Ovrigt " 中似乎有一个空白 space。可能是这样吗?
假设文件的第一行总是包含列名,这里有一个快速实现的方法:
// Define the array that will contain the columns names
$columns = [];
foreach($rows as $i => $row)
{
$row = explode("\t", $row);
// For the first row get the get the column names
if ($i == 0)
{
$columns = $row;
continue; // Skip this iteration
}
// Map each column name to every item in the row
$_row = array();
array_walk($row, function ($value, $index) use (&$_row, $columns)
{
$_row[$columns[$index]] = $value;
});
$row = $_row;
// You can now access row items with
// $row['X'], $row['Y'], etc.
...
}
如果您确切知道所有列都将出现在文件中(无论顺序如何),您可以更进一步,将文件中的列名称映射到对应的模型 属性 名称。这将使验证和填充每个模型更加无缝:
// Define the array that will contain the columns names
$columns = [];
// Define the column mapping
// 'column name' => 'model property name'
$columnMap = [
'X' => 'X',
'Y' => 'Y',
'Ar' => 'year',
'Provnr' => 'provnr',
'id' => 'customer_id'
];
foreach($rows as $i => $row)
{
// Assuming the column names are always on the first row
if ($i == 0)
{
$columns = $row;
// Replace Swedish special chars with simple Latin chars
array_walk($columns, function (&$item)
{
$item = str_replace(
['ä', 'å', 'ö', 'Ä', 'Å', 'Ö'],
['a', 'a', 'o', 'A', 'A', 'O'],
trim($item)
);
});
continue; // Skip this iteration
}
// Map each column name to every item in the row
$_row = array();
array_walk($row, function ($value, $index) use (&$_row, $columns, $columnMap)
{
$_row[$columnMap[$columns[$index]]] = $value;
});
$row = $_row;
// Pass the $row directly to the validator because the mapped keys will work
$validator = Validator::make($row, Sample::$insertRules);
if($validator->passes()){
$sample = New Sample;
// You can iterate over the row and assign each value automatically
// because each item key is mapped to a property name
foreach ($row as $property => $value)
$sample->{$property} = $value;
$sample->save();
}
else
{
Session::flash('notice', 'Something is wrong!');
Session::flash('sample', $row[3]);
return Redirect::to('import');
}
}