我正在尝试借助 php 表单向我的数据库插入一个新行。
CREATE TABLE person (
first_name VARCHAR(30) NOT NULL,
last_name VARCHAR(30) NOT NULL,
languages SET('english', 'greek', 'german', 'japanese', 'spanish', 'italian', 'french', 'wookie', 'klingon', 'other') NOT NULL,
pid INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY(pid)
);
首先,我有上面的MySQL表。
然后,使用以下代码,我获取所有内容的字段值
<form class="sform" method="post">
<input type="text" name="first_name" value="" placeholder="First name" maxlength="30">
<input type="text" name="last_name" value="" placeholder="Last name" maxlength="30">
<select multiple="multiple" id="languages" name="languages[]">
<option value='english'>English</option>
<option value='greek'>Greek</option>
<option value='german'>German</option>
<option value='japanese'>Japanese</option>
<option value='spanish'>Spanish</option>
<option value='italian'>Italian</option>
<option value='french'>French</option>
<option value='wookie'>Wookie</option>
<option value='klingon'>Klingon</option>
<option value='other'>Other</option>
</select>
</form>
请注意,此时这是一个多选表单。(一个人可以说一种以上的语言)
然后,使用 php
我获取表的每个元素的值,但对于我最感兴趣的元素,我执行以下操作:
$qfirst_name = $_POST['first_name'];
$qlast_name = $_POST['last_name'];
$qlanguages = "'" . implode("','", $_POST['languages']) . "'";
我在这里调用 implode
方法的原因是,所以我以以下形式返回一个字符串: ex.'english','greek'
但是,这不是MySQL接受SET初始化的方式,因此,我像这样替换single quotes
:
$qlanguages = str_replace(''', '', $qlanguages);
现在,$qlanguages将是:ex.english,greek
但这仍然不够接近,所以最后一步是在变量的开头和结尾应用引号,如下所示:$qlanguages = '''.$qlanguages.''';
最后,$qlanguages采用正确的格式'english,greek'
使用以下代码插入到数据库中:
$sql1 = "INSERT INTO person (first_name, last_name, languages)
VALUES ('$qfirst_name', '$qlast_name', '$qlanguages')";
然后我连接到我的数据库以将条目添加到数据库中此处注意还有另一个文件可以建立连接,我刚刚将其包含在 php 文件的顶部。
if ($dbconn->query($sql1)) {
echo "SUCCESS";
}
else {
echo "FAIL";
}
我已经尽可能地解释了我的步骤,我的问题是:为什么当我在查询中包含SET
字段时,我无法在数据库中插入新person
。我错过了什么?
对不起,长帖子。
你这样做了:
$qlanguages = "'english,greek'";
$sql1 = "INSERT INTO person (first_name, last_name, languages)
VALUES ('$qfirst_name', '$qlast_name', '$qlanguages')";
所以你得到了这个:
$sql1 = "INSERT INTO person (first_name, last_name, languages)
VALUES ('qfirst_name', 'qlast_name', ''english,greek'')";
您可以看到"双"单"引号代替语言
SET
数据类型在内部存储为二进制数字。IIRC 您可以利用这一事实并省去所有这些字符串操作。另外,如果您将我放在该网页前面5秒钟,我可以删除您的数据库。您应该使用预准备语句来降低 SQL 注入攻击风险。
<form class="sform" method="post">
<input type="text" name="first_name" value="" placeholder="First name" maxlength="30">
<input type="text" name="last_name" value="" placeholder="Last name" maxlength="30">
<select multiple="multiple" id="languages" name="languages[]">
<option value='1'>English</option>
<option value='2'>Greek</option>
<option value='4'>German</option>
<option value='8'>Japanese</option>
<option value='16'>Spanish</option>
<option value='32'>Italian</option>
<option value='64'>French</option>
<option value='128'>Wookie</option>
<option value='256'>Klingon</option>
<option value='512'>Other</option>
</select>
</form>
<?php
$qfirst_name = $_POST['first_name'];
$qlast_name = $_POST['last_name'];
$qlanguages = array_sum($_POST['languages']);
$stmt = $dbconn->prepare("INSERT INTO person (first_name, last_name, languages) VALUES (?, ?, ?)");
$stmt->bind_param("ssd", $qfirst_name, $qlast_name, $qlanguages);
if ($stmt->execute($sql1)) {
echo "SUCCESS";
}
else {
echo "FAIL";
}
?>
未经测试,但几年前我做了类似的事情,当时我愚蠢到使用SET
列。现在我建议使用单独的语言表。