我需要在添加新类别和更改现有类别时为类别设置自定义顺序。我相信代码和SQL查询在两种情况下都是一样的
在我的webshop_categories
- 表中,我有一个sorting_order INT
- 列,用于阻止类别应该输出到观看者的顺序。
以下是我的表(so = sorting_order)的简化示例:
id | name | so
--------------------
1 | Shoes | 1
2 | Hats | 2
3 | Bags | 3
4 | Coats | 4
5 | Rings | 5
当添加未指定的类别时,我只会填写表格,并按如下方式提交:
(这将添加一个新类别,并将其放在最后。在这种情况下,so
将设置为6)
$so = $dbh->query('SELECT (MAX(so)+1) FROM webshop_categories WHERE so != 0')->fetchColumn();
$ins = $dbh->prepare('INSERT INTO webshop_categories (name, so)')->execute([$_POST['name'], $so]);
但有时候我需要改变类别的顺序
我可能需要将Coats移到鞋子和帽子之间
这需要更新周围的类别
在这种情况下;无论我将这个类别移动到何处,我们都需要执行+1
到so
列,以便为此移动腾出空间。但显然,增量需要停在高士。
反之亦然。如果我将帽子移到大衣和戒指之间,我需要-1
做大衣和手袋。试。
实现这一目标的好方法是什么?
更改是通过form select
进行的,其中选项move to top
(表示1
)和Move to after ?cat_name?
。
我相信在添加带有预设排序顺序的新类别时,它将是相同的代码。具有相同选项的相同选择列表。
我是否需要查询并获取需要使用so
更新+/- 1
的所有类别,并循环显示这些类别以进行更改?
或者可能有一种方法可以同时对它们进行+/- 1
而无需循环遍历每一个?
复制所有行(进入PHP数组),删除它们,创建一个更新so
的新列表,然后将它们重新插入,不应该只是为了进行这些更改......但这是我认为有效的一种方式......
答案 0 :(得分:1)
有多种方法可以做到这一点,但具体方法实际上取决于您的结构。
那就是说,无论你接近它,你只需要增加或减少你正在改变的那个之下或之上的那些:
当新so
值为:
我建议只选择您需要更新的行,因此“if less than”等逻辑将出现在select查询中。然后,您只需使用该结果数组进行更新。
示例:
1 = shoes
2 = hats
3 = bags
4 = coats
5 = rings
警告:此代码非常老派,仅用于快速说明,以显示逻辑。它没有经过测试,可能有错误,请在使用前进行测试。
示例代码函数将更改大于或小于的任何值,例如4到2,或2到4等等
// You'd retrieve the requested change data from your form (or whatever)
update_categories_so(
(int) $_POST['category_id'],
(int) $_POST['current_so'],
(int) $_POST['new_so']
);
/**
* @param int $categoryIdForChangedSo
* @param int $currentSo
* @param int $newSo
*
* @return void
*/
function update_categories_so($categoryIdForChangedSo, $currentSo, $newSo)
{
// Determine if incrementing or decrementing
$increment = $newSo < $currentSo ? true : false;
// Set increment or decrement var for the update
$changeBy = $increment ? '+' : '-';
// Set the where clause to get the current category_ids
// which would need to be updated
$selectWhereClause = $increment
? "'so' >= $newSo AND 'so' < $currentSo"
: "'so' <= $newSo AND 'so' > $currentSo";
$selectSql = "
SELECT
`category_id`
FROM
`webshop_categories`
WHERE
{$selectWhereClause}
";
// Return the results into $categoryIdsForUpdate
// Update the categories which are affected by the main change,
// from the array from the DB
$updateOtherSoSql = "
UPDATE
`webshop_categories`
SET
'so' = 'so' {$changeBy} 1
WHERE
'category_id' IN ({$categoryIdsForUpdate})
";
// Update the main one being changed
$updateRequestedSosql = "
UPDATE
`webshop_categories`
SET
so = {$newSo}
WHERE
'category_id' = {$categoryIdForChangedSo}
";
}
我不知道您是如何处理错误的,但是您可以返回结果 - 检查查询是否正常等等
有关$selectWhereClause
的更多信息,请了解其工作原理:
有关从数据库返回的$categoryIdsForUpdate
数据的更多信息。
下面的示例数组是将“so”4(Coats)更改为2(当前为Hats)。 (示例ID不是1-5,以避免与“so”值混淆)
category_id => so
$categoryIdsForUpdate = [
10 => 1, // (shoes) not included as is less than new "so"
13 => 2, // (hats) incremented by 1
17 => 3, // (bags) incremented by 1
18 => 4, // (coats) not included as is current category_id
27 => 5, // (rings) not included as greater than current "so"
];