我有一个脚本,导入记录到多个数据库表,所有关系到一个父实体(地址)。从CSV导入,记录已经存在其他成功,否则失败
如果地址已经存在,应该根据csv更新额外的列。对于所有其他实体也是如此。一个计数器($exist++
)应该增加或者一个数组($existingRecords
)应该填入已经存在的记录。
如果记录中必填字段为空,则应将该记录添加到另一个阵列($failedRecords
)或另一个计数器($failed++
)应增加。
如果地址尚不存在并且应该使用所有字段创建,只需要增加一个计数器($successful++
)。
最后,我有一个数组$result
,它给出用户反馈的失败,成功和已经存在(但更新)记录的数量。
我怎样才能以一个很好的干净方式实现这一点,而不会将我当前的脚本搞得太乱了?因为现在正在发生的情况是,如果已有记录$exist
计数器增加,但$successful
计数器也是这样,并且我只希望$exist
计数器增加,如果记录已经存在,并且只有$successful
计数器应增加,如果记录仍然存在必须添加并成功添加。 $failed
计数器也一样。
这里是我的脚本(与我试过):
public function import(CsvFile $csv) {
$root = __DIR__.'/../../../../../';
$file = $root.'var/data/'.$csv->getCsvName();
$fp = fopen($file, "r");
$batchSize = 25;
$header = null;
$successful = 0;
$failed = 0;
$exist = 0;
$results = [];
while ($row = fgetcsv($fp, null, ";")) {
if ($header === null) {
$header = $row;
continue;
}
$record = array_combine($header, $row);
// cast all values to correct data types
foreach ($record as $key => &$value) {
if (strpos($key, 'datum') !== false ||
strpos($key, 'tijdstip') !== false &&
strlen($value) == 8 &&
is_numeric($value)
) {
$value = \DateTime::createFromFormat('Ymd', $value);
}
if ($value === "") {
$value = null;
}
if (is_numeric($value)) {
intval($value) == $value ? $value = (int)$value : $value = (float)$value;
}
}
// required fields
if (!$record['name'] ||
!$record['surname'] ||
!$record['email'] ||
!$record['phone'] ||
!$record['street'] ||
!$record['houseNo'] ||
!$record['town'] ||
!$record['postcode'] ||
!$record['location'] ||
!$record['lecture'] ||
!$record['session'] ||
) {
$failed++;
continue;
}
$student = $this->em->getRepository(Student::class)->findStudent(
$record['name'], $record['surname'],
$record['email'], $record['phone']
);
if (!$student) {
$student = new Student();
$student->setName($record['name']);
$student->setSurname($record['surname']);
$student->setEmail($record['email']);
$student->setPhone($record['phone']);
} else {
$exist++;
}
$student->setAge($record['age']);
$student->setLength($record['length']);
$address = $this->em->getRepository(Address::class)->findOneBy([
'street' => $record['street'],
'houseNo' => $record['houseNo'],
'town' => $record['town'],
'postcode' => $record['postcode'],
);
if (!$address) {
$address = new Address();
$address->setStreet($record['street']);
$address->setHouseNo($record['houseNo']);
$address->setPostcode($record['postcode']);
$address->setTown($record['town']);
}
$student->setAddress($address);
$lecture = $this->em->getRepository(Lecture::class)->findOneBy([
'location' => $record['location'],
'lecture' => $record['lecture'],
'session' => $record['session'],
]);
if (!$lecture) {
$lecture = new Lecture();
$lecture->setLocation($record['location']);
$lecture->setLecture($record['lecture']);
$lecture->setSession($record['session']);
}
$lecture->setTime($record['time']);
$lecture->setSubject($record['subject']);
$student->setLecture($lecture);
$validationErrors = $this->validator->validate($student);
if (!count($validationErrors)) {
$this->em->persist($student);
$successful++;
}
if (($successful % $batchSize) == 0) {
$this->em->flush();
}
}
fclose($fp);
$csv->setImported(true);
$this->em->persist($csv);
$this->em->flush(); // Also persist objects that did not make up an entire batch
$results['successful'] = $successful;
$results['failed'] = $failed;
$results['exist'] = $exist;
return $results;
}