我在我的MySQL数据库中创建了TINYINT列来解释布尔变量,它基于在html中是否选中复选框而在DB中存储值(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();
}
?>发布于 2017-03-12 02:37:08
通常,当您接受用户输入时,您希望像这样参数化查询。您的问题是,您要输入的用户输入(或者至少是潜在的用户输入)是列名,而不是值。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中可能有点反模式。这可能会使用类似于:UPDATE projectDB.Members SET Enabled = 1 WHERE name=:name AND username =:currentUser的查询;您也可以使用EAV模型的列,该列具有首选项或某种类型的位掩码/列表(但同样,这是一种SQL反模式,因为您试图在一列中打包多个信息。
https://stackoverflow.com/questions/42743074
复制相似问题