我在 MySQL 数据库中创建了 TINYINT 列来解释 bool 变量,该变量基于 html 中是否选中复选框来将值(0 表示 false,其他所有值表示 true)存储在数据库中。但是当调用 php 文件时它不会更新这些值。我的SQL有问题吗? TINYINT 是否按如下方式输入?简单地用 0 和 1 来实现?
<?php
include_once("createConnection.php");
session_start();
$checkbox = $_POST['name'];
$checked = $_POST['checked'];
$currentUser = $_SESSION['validUser'];
if($checked=='yes'){
$request='UPDATE projectDB.Members
SET :name=1 WHERE username=:currentUser';
$preparedStatement = $bdd->prepare($request);
$preparedStatement->bindParam(':name', $checkbox, PDO::PARAM_STR);
$preparedStatement->bindParam(':currentUser', $currentUser, PDO::PARAM_STR);
$preparedStatement->execute();
}
else{
$request='UPDATE projectDB.Members
SET :name=0 WHERE username=:currentUser';
$preparedStatement = $bdd->prepare($request);
$preparedStatement->bindParam(':name', $checkbox, PDO::PARAM_STR);
$preparedStatement->bindParam(':currentUser', $currentUser, PDO::PARAM_STR);
$preparedStatement->execute();
}
?>
最佳答案
通常,当您接受用户输入时,您希望像这样参数化您的查询。您的问题是您接受的用户输入(或至少是潜在的用户输入)是列名称而不是值。 PHP 正在将您的查询转换为如下内容:
UPDATE projectDB.Members
SET 'name'=1 WHERE username='currentUser'
这并没有做你想要的事情(它告诉 SQL 更新名为“name”的字符串,而不是更新名为 name
的列)。
如果您不清理数据,您仍然会面临风险 - 基本上您有两个选择:
在代码中拥有可接受的列名称白名单;验证传入字符串是否与该白名单中的条目完全匹配,如果是,则将其用作列名称。这里的缺点是数据模型中的列名称散布在代码和 HTML 中。例如:
$chkcols['name1'] = true;
$chkcols['name2'] = true;
$chkcols['name3'] = true;
...
if ($chkcols[name] == true) ...;
或
提出一个不同的数据模型,也许像 EAV 这样,您不必处理动态列名称。这里的缺点是 EAV 可能有点像 SQL 中的反模式。这可能会使用类似以下的查询:
更新projectDB.Members SET Enabled = 1 WHERE name=:name AND username =:currentUser
;除了 EAV 模型之外,您还可以拥有一个具有首选项或某种位掩码/列表的列(但同样,这是一种 SQL 反模式,因为您试图将多条信息打包到单个列中。
关于php - MySQL输入TINYINT语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42743074/