好吧,当您在数据库中有项目并且您收到包含更改的项目集的新文档时,您显然必须更新数据库。最简单的方法之一是删除所有以前的项目并插入新列表。但是,如果项目与其他数据相关,则不能这样做。因此,您必须应用这种比较两个列表的技术。您在数据库中有项目,在文档更改后您有来自客户端的项目,并且使用以下命令,您可以将要插入数据库的内容、只需要更新的内容和要从数据库中删除的内容分开。下面是一个简化的例子。
$a = [1,2,3,4,5]; //elements in database
$b = [2,3,4,6]; //elements after document save
$del = array_diff($a, $b);
//for delete 1, 5
$ins = array_diff($b, $a);
//for insert 6
$upd = array_intersect($a, $b);
//for update 2, 3, 4
如您所见,这只是比较元素,但如果要插入真实数据,则必须切换到关联数组并比较键。你需要数组看起来像这样:
{
"15":{"employee_id":"1","barcode":"444","is_active":"1"},
"16":{"employee_id":"1","barcode":"555","is_active":"1"},
"17":{"employee_id":"1","barcode":"666","is_active":"1"},
"18":{"employee_id":"1","barcode":"777","is_active":"1"}
}
在这里,您从数据中提取了 ID 并放置在数组键位置。在服务器端,可以使用 PDO 轻松获取该数组:
$sth->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
请注意,这将从结果集中删除第一列。因此,如果您想在两个地方都使用 ID,请使用:“SELECT id AS arrkey, id, ... FROM ...”。
在服务器端,当您制作数组时,您不需要所有数据,只需获取 id-s。这一切都需要比较,因为关键只重要:
[16=>16, 17=>17, 18=>18, 19=>19, 20=>20];
在客户端,使用 JavaScript,您必须制作相同的结构化对象数组,以便在服务器上进行比较。当您在客户端上有新项目时,只需使用 Math.random() 来生成随机密钥,因为这并不重要。
let cards = {};
cards[Math.random()] = {
employee_id: something,
barcode: something,
is_active: something
}
之后,从客户端你会得到这样的数组:
{
"16":{"employee_id":"1","barcode":"555","is_active":"1"},
"17":{"employee_id":"1","barcode":"666","is_active":"1"},
"18":{"employee_id":"1","barcode":"777","is_active":"1"},
"0.234456523454":{"employee_id":"1","barcode":"888","is_active":"1"}
}
删除 Id 为 15 的项目,更改 16、17、18(或不更改,无论如何您都会更新它们),并添加新项目。在服务器上,您可以应用 3 种方式比较:array_diff_key和array_intersect_key。
所以,最后,这个服务器端代码在我的例子中看起来如何。第一个循环在数组键上,第二个循环是动态地制作 UPDATE/INSERT 语句。
//card differences
$sql = 'SELECT card_id AS arrkey, card_id FROM card WHERE (employee_id = ?)';
$sth = $this->db->prepare($sql);
$sth->execute([$employee_id]);
$array_database = $sth->fetchAll(PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
$array_client = json_decode($_POST['...'], true);
//cards update
foreach (array_intersect_key($array_database, $array_client) as $id => $data) {
$query = 'UPDATE card SET';
$updates = array_filter($array_client[$id], function ($value) {return null !== $value;}); //clear nulls
$values = [];
foreach ($updates as $name => $value) {
$query .= ' '.$name.' = :'.$name.',';
$values[':'.$name] = $value;
}
$query = substr($query, 0, -1); // remove last comma
$sth = $this->db->prepare($query . ' WHERE (card_id = ' . $id . ');');
$sth->execute($values);
}
//cards insert
foreach (array_diff_key($array_client, $array_database) as $id => $card) {
$prep = array();
foreach($card as $k => $v ) {
$prep[':'.$k] = $v;
}
$sth = $this->db->prepare("INSERT INTO card ( " . implode(', ',array_keys($card)) . ") VALUES (" . implode(', ',array_keys($prep)) . ")");
$sth->execute($prep);
}
//cards delete
foreach (array_diff_key($array_database, $array_client) as $id => $data) {
$sth = $this->db->prepare('DELETE FROM card WHERE card_id = ?');
$sth->execute([$id]);
}