我有一个可选服装项目列表作为复选框,数量可能比下面的 5 个更多。
shoes, pants, skirt, socks, jacket //list of possible choices
在所选项目的 jquery 中创建一个逗号分隔的数组。假设选择以下内容:
shoes, socks, jacket //array posted as $_POST['clothes']
在数据库中,每个客户在服装表中都有这些选项,在服装项目下有“是”或“否”。然而,服装项目的命名略有不同,但映射到相同的选项:
插入前的“衣服”表
customer_id dress_shoes elegant_pants long_skirt ankle_socks biker_jacket
1 no yes no no no
使用 $_POST['clothes'],我尝试循环遍历数组,将相应字段更新为
yes
,将数据库中的非对应字段更新为 no
。我很难做到这一点。
插入后的“衣服”表
customer_id dress_shoes elegant_pants long_skirt ankle_socks biker_jacket
1 yes no no yes yes
我尝试使用
array_intersect()
将项目标记为“是”:
$clothesArray = array("shoes", "socks", "jacket"); // Posted clothes
$clothesArrayAll = array("shoes", "pants", "skirt", "socks", "jacket"); // All clothes
$common = array_intersect($clothesArrayAll,$clothesArray);
print_r($common);
Array ( [0] => shoes [3] => socks [4] => jacket )
我试图以某种方式循环遍历
$clothesArrayAll
,对普通衣服说“是”,对数组中的所有其他衣服说“不”。然后,我尝试通过 PDO 更新“衣服”表,以最有效的方式将每个相应字段设置为“是”或“否”。在获得上面的常见衣服阵列后,我陷入困境,不知道如何继续。
我认为你走在正确的道路上。我只需添加一个包含字段映射的附加数组,例如
$mappingArray = array('shoes' => 'dress_shoes', 'socks' => 'ankle_socks', ...);
使用此数组和前一个数组,您可以循环遍历并根据
$common
字段的值以及 $mappingArray
中的键相应地设置 SQL
用示例编辑(可能不是最优化的):
$finalArray = array();
foreach ($mappingArray as $key => $value) {
$finalArray[$value] = in_array($key, $common) ? 'yes' : 'no';
}
$finalArray
现在将为与您的数据库表匹配的每个值提供是/否语句。
编辑以包含 PDO:我实际上会按如下方式更新上述循环:
$finalArray = array();
$sql = "INSERT INTO cloths (" . implode(",", array_values($mappingArray)) . ") VALUES (:" . implode(",:", array_values($mappingArray)) . ")";;
foreach ($mappingArray as $key => $value) {
$finalArray[":" . $value] = in_array($key, $common) ? 'yes' : 'no';
}
$q = $conn->prepare($sql);
$q->execute($finalArray);
与这个一起飞行,所以类似的事情......
为什么不更改您的 HTML 字段名称以匹配您的数据库名称,然后在数据库中设置默认值“否”...
$cols='INSERT INTO clothes ';
$values=' VALUES ';
$join='(';
foreach ($_POST as $key=>$val) {
$cols.=$join . $key;
$values=$join . ':' . $key;
$join=',';
}
$qry=$cols . ')' . $values . ')';
$stmt = $dbh->prepare($qry);
foreach ($_POST as $key=>$val) {
$stmt->bindParam(':' . $key, $_POST[$key]);
}
但是您可能想检查发布的名称是否有效的列名称 - 您可以使用
从表中获取列名称和类型DESC clothes;
首要任务是验证提交的有效负载。您可能想确保 customer_id 是正整数并且衣服项目与可能性白名单匹配。
因为需要白名单,所以它可以起到第二个目的,即存储默认值。
在构建 PDO 查询之前,请按照以下准备步骤对输入数据进行清理和标准化。
代码:(演示)
$defaults = [
"shoes" => 'no',
"pants" => 'no',
"skirt" => 'no',
"socks" => 'no',
"jacket" => 'no',
];
$_POST['id'] = '2';
$_POST['clothes'] = "shoes, socks, jacket";
$ticked = array_fill_keys(explode(', ', $_POST['clothes']), 'yes');
$yesses = array_intersect_key($ticked, $defaults);
$row = ['id' => (int) $_POST['id']] + array_replace($defaults, $yesses);
从这里开始,不清楚您是要插入还是更新一行。如果更新,则应与提交数据一起传递主键值以确定要修改的行。
代码:(PHPize演示)
$sql = sprintf(
'INSERT INTO clothes
(customer_id, dress_shoes, elegant_pants, long_skirt, ankle_socks, biker_jacket)
VALUES (%s)',
implode(',', array_fill(0, count($row), '?'))
);
($pdo->prepare($sql))->execute(array_values($row));
如果更新行,则调整查询,但以几乎相同的方式使用提交数据。 (PHPize 演示)
$_POST['id'] = '1';
$_POST['clothes'] = "shoes, socks, jacket";
$ticked = array_fill_keys(explode(', ', $_POST['clothes']), 'yes');
$yesses = array_intersect_key($ticked, $defaults);
$row = ['id' => (int) $_POST['id']] + array_replace($defaults, $yesses);
//var_export($row);
$sql = <<<SQL
UPDATE clothes
SET dress_shoes = :shoes,
elegant_pants = :pants,
long_skirt = :skirt,
ankle_socks = :socks,
biker_jacket = :jacket
WHERE customer_id = :id
SQL;
($pdo->prepare($sql))->execute($row);