我正在尝试通过CSV文件并提取其所有内容。
导入内容后,我需要将它们插入mysql数据库表,但在此之前,我需要检查这些记录是否存在。如果某个记录没有,则导入此寄存器。
我有标题和所有的内容,我已经创建了一个数组与此信息,但我不知道它是否100%正确。这是我的实际代码:
function csv_content_parser($content) {
foreach (explode("n", $content) as $line) {
// Generator saves state and can be resumed when the next value is required.
yield str_getcsv($line);
}
}
$archivo = fopen($route, "r");
// Get content from csv file.
$content = file_get_contents($adjunto);
// Create arrays from csv file's lines.
$data = array();
$headers = array();
$rows = array();
//get all content
foreach ($this->csv_content_parser($content) as $fields) {
array_push($data, $fields);
}
//get headers
foreach($data[0] as $dat){
array_push($headers, $dat);
}
//get all content of csv without headers
for($i=1; $i<count($data); $i++){
array_push($rows, $data[$i]);
}
//close the file
fclose($archivo);
csv文件的内容(这是一个示例文件)例如(我需要创建一个通用导入器):
Array
(
[0] => Array
(
[0] => ggggg@gmail.com
[1] => david
[2] => 005
[3] => hola
[4] => eee
[5] => eee
)
[1] => Array
(
[0] => ggggg@gmail.com
[1] => david
[2] => 005
[3] => hola
[4] => eee
[5] => eee
)
)
And my headers:
Array
(
[0] => Email
[1] => Name
[2] => Identification
[3] => Note
[4] => Field Label 1
[5] => Field Label 2
)
我的问题是:这是一个好的解决方案还是有更好的解决方案?我需要将这些数据插入到数据库中。怎么才能做到呢?
更新:
<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Listado extends Model
{
protected $table = 'listado';
protected $fillable = [
'nomape', 'direccion', 'provincia', 'ciudad', 'cp', 'telefono', 'movil', 'id_teleoperadora'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [];
public function scopeTodos( $query )
{
return $query->orderBy('nomape', 'ASC')->orderBy('telefono', 'ASC');
}
public function scopeSinAsignar( $query, $id_llamadas )
{
$query->whereIn('id', $id_llamadas)->whereNull('id_teleoperadora');
}
public static function Filtrado($request)
{
$query = self::query();
if($request['direccion']) {
$query->where('direccion', 'like', '%' .$request['direccion']. '%');
}
if($request['ciudad']) {
$query->where('ciudad', $request['ciudad']);
}
if($request['cp']) {
$query->where('cp', $request['cp']);
}
/*if($request['teleoperadora']) {
$query->where('id_teleoperadora', $request['teleoperadora']);
}*/
return $query;
}
public function scopeConEstado( $query, $nombreEstado )
{
return $query->whereHas('llamada.estado', function ($query) use ($nombreEstado) {
$query->whereNombre($nombreEstado);
})->orWhereDoesntHave('llamada');
}
public function scopeConEstados( $query, $nombresEstado )
{
return $query->whereHas('llamada.estado', function ($query) use ($nombresEstado) {
$query->whereIn('nombre', $nombresEstado);
})->orWhereDoesntHave('llamada');
}
public function llamada()
{
return $this->hasOne('AppLlamada', 'id_listado', 'id')->latest();
}
public function llamada_test()
{
return $this->hasOne('AppLlamada', 'id', 'id_listado');
}
/**
* RETURN OPERATOR
*/
public function teleoperadora()
{
return $this->hasOne('AppUser', 'id', 'id_teleoperadora')->withDefault(['nombre' => 'NINGUNA']);
}
/**
* RETURN CALL DATA
*/
public function callStatusName()
{
return $this->hasOne('Appllamada', 'id_listado', 'id');
}
}
更新2
我所有的函数代码
function csv_content_parser($content) {
foreach (explode("n", $content) as $line) {
// Generator saves state and can be resumed when the next value is required.
yield str_getcsv($line);
}
}
public function uploadListing(Request $request)
{
$adjunto = $request->file('attached');
$route = "";
if(isset($adjunto)){
$name = $adjunto->getClientOriginalName();
$result = $adjunto->storeAs('importaciones', $name, 's4');
$route = public_path('storage/importaciones/'.$name);
}else{
return "Error al adjuntar recibo de envío, consulte al administrador del sistema";
}
//Abrimos nuestro archivo
$archivo = fopen($route, "r");
// Get content from csv file.
$content = file_get_contents($adjunto);
// Create arrays from csv file's lines.
$data = array();
$headers = array();
$rows = array();
//get all content
foreach ($this->csv_content_parser($content) as $fields) {
array_push($data, $fields);
}
//get headers
foreach($data[0] as $dat){
array_push($headers, $dat);
}
//get all content of csv without headers
for($i=1; $i<count($data); $i++){
array_push($rows, $data[$i]);
}
Listado::insertOrIgnore(array_map(function($row) {
return array_combine($headers, $row);
}, $rows));
//Cerramos el archivo
fclose($archivo);
}
更新3
function csv_content_parser($content) {
foreach (explode("n", $content) as $line) {
// Generator saves state and can be resumed when the next value is required.
yield str_getcsv($line);
}
}
public function uploadListing(Request $request)
{
$adjunto = $request->file('attached');
$route = "";
if(isset($adjunto)){
$name = $adjunto->getClientOriginalName();
$result = $adjunto->storeAs('importaciones', $name, 's4');
$route = public_path('storage/importaciones/'.$name);
}else{
return "Error al adjuntar recibo de envío, consulte al administrador del sistema";
}
//Abrimos nuestro archivo
$archivo = fopen($route, "r");
// Get content from csv file.
$content = file_get_contents($adjunto);
// Create arrays from csv file's lines.
$data = array();
$headers = array();
$rows = array();
//get all content
foreach ($this->csv_content_parser($content) as $fields) {
array_push($data, $fields);
}
//get headers
foreach($data[0] as $dat){
array_push($headers, $dat);
}
//get all content of csv without headers
for($i=1; $i<count($data); $i++){
array_push($rows, $data[$i]);
}
Listado::insertOrIgnore(array_map(function($row) use($headers) {
return array_combine($headers, $row);
}, $rows));
//Cerramos el archivo
fclose($archivo);
}
As per docs:
DB::table('listado')->insertOrIgnore(array_map(fn($row) => array_combine($headers, $row), $rows));
既然你有Eloquent模型,你可以使用Eloquent的insert()
方法:
Listado::insertOrIgnore(array_map(fn($row) => array_combine($headers, $row), $rows));
既然你说了下面的话
我需要检查这些记录是否存在。如果某个记录没有,则导入此寄存器。
我选择了insertOrIgnore()
方法,但也许你想要其他方法。幸运的是,Laravel提供了一堆类似的方法,用于稍微不同的用例。
在PHP 7.4之前,array_map(fn($row) => array_combine($headers, $row), $rows)
必须为:
array_map(function($row) use($headers) {
return array_combine($headers, $row);
}, $rows)