foreach ($outlineUrls as $outlineUrl) {
$html = file_get_contents($outlineUrl);
$DOMParser = new \DOMDocument();
$DOMParser->loadHTML($html);
$changeForMyDB = [
'remote_id' => '',
'region' => '関西',
'link' => json_encode($outlineUrl),
'name' => '',
'price' => '',
'extend' => '',
'address' => '',
'hows_old' => '',
'rooms' => '',
'old' => '',
'entery' => '',
'balcon_m2' => '',
'company_name' => '',
'script_from' => ''
];
$allPTags = $DOMParser->getElementsByTagName('p');
foreach($allPTags as $ptag){
if($ptag->getAttribute('class') == 'c-name'){
$changeForMyDB['name'] = trim($ptag->nodeValue);
}
}
$changeForMyDB['address'] = trim($DOMParser->getElementsByTagName('dd')[0]->nodeValue);
$allTables = $DOMParser->getElementsByTagName('table');
foreach($allTables as $table){
foreach($table->getElementsByTagName('tr') as $tr){
$property = trim($tr->getElementsByTagName('th')[0]->nodeValue);
$value = trim($tr->getElementsByTagName('td')[0]->nodeValue);
switch ($property) {
case '物件名':
$changeForMyDB['name'] = $value;
break;
case '販売価格':
$changeForMyDB['price'] = $value;
break;
case '専有面積':
$changeForMyDB['extend'] = $value;
break;
case '所在地':
$changeForMyDB['address'] = $value;
break;
case '総戸数':
$changeForMyDB['hows_old'] = $value;
break;
case '間取り':
$changeForMyDB['rooms'] = $value;
break;
case '竣工時期':
$changeForMyDB['old'] = $value;
break;
case '管理会社':
$changeForMyDB['company_name'] = $value;
break;
case '入居時期':
$changeForMyDB['entery'] = $value;
break;
case '入居時期':
$changeForMyDB['entery'] = $value;
break;
case 'バルコニー面積':
$changeForMyDB['balcon_m2'] = $value;
break;
default:
# code...
break;
}
}
}
if(Estates::where('link','=',$outlineUrl)->count() > 0)
{
$this->error('There is link.');
} else {
Estates::insertGetId($changeForMyDB);
$this->line('Data saved.');
}
但问题就在这里。它没有检查就插入了数据! 你知道是什么问题吗?谢谢你的帮助。
You can use the updateOrCreate() method to achieve the goal of only inserting if the record does not exist:
$estate = Estates::updateOrCreate(['link' => $outlineUrl], $changeForMyDB);
This will check if there is an Estate::where('link', '=', $outlineUrl)
. If none is found, it will create a new Estate´ and add all data from
$changeForMyDBto it. If one exists, it will fetch it from the database, add all data from
$changeForMyDB`. Then it will persist the changes. Read more about that here: https://laravel.com/docs/5.7/eloquent#other-creation-methods
To avoid issues with concurrent requests, you should also wrap your update within a database transaction. This ensures that the database has the same state when you checked for uniqueness as when you store your data.
DB::transaction(function () {
$estate = Estates::updateOrCreate(['link' => $outlineUrl], $changeForMyDB);
});
If you don't want to update existing entries, use something like this:
DB::transaction(function () {
if (Estates::where('link','=',$outlineUrl)->count() === 0) {
$estate = Estates::create($changeForMyDB);
}
});
Beware that Estates::create($data)
and Estates::insert($data)
are not the same. The create($data)
function will create a model, fill it with the $data
and return the persisted model. It will also fire all Eloquent events that are relevant for the create method. The insert($data)
method on the other hand will not create an Eloquent model and will therefore also not fire any Eloquent events. It will directly insert the data into the database. This is more lightweight and faster, but you should keep that in mind.
If you want to check if the record already existed and report some kind of error, you can check with this:
if (!$estate->wasRecentlyCreated()) {
// report error here
}