Php 将HTML select中的值添加到MySQL查询中
我最近一直在重新学习HTML和MySQL,并深入研究PHP。我遇到了一些问题(可能是因为我仍在学习PHP),无法使情况正常工作。我的服务器上运行着一个MySQL实例,它也是一个IIS7 web服务器,安装了PHP。我用HTML和PHP创建了一个表单,用于向表中添加条目,另一个表单用于显示表并对其进行过滤(如果需要)。现在在我看来它看起来很乱,而且会说它是湿的。为了遵循DRY的原则,我想将后一部分(当前为每个可能的表列使用文本框和按钮进行筛选)更改为使用下拉列表选择要筛选的列,并使用单个文本框填充要筛选的值。这是我的当前代码(带有多个文本框和按钮):Php 将HTML select中的值添加到MySQL查询中,php,html,mysql,Php,Html,Mysql,我最近一直在重新学习HTML和MySQL,并深入研究PHP。我遇到了一些问题(可能是因为我仍在学习PHP),无法使情况正常工作。我的服务器上运行着一个MySQL实例,它也是一个IIS7 web服务器,安装了PHP。我用HTML和PHP创建了一个表单,用于向表中添加条目,另一个表单用于显示表并对其进行过滤(如果需要)。现在在我看来它看起来很乱,而且会说它是湿的。为了遵循DRY的原则,我想将后一部分(当前为每个可能的表列使用文本框和按钮进行筛选)更改为使用下拉列表选择要筛选的列,并使用单个文本框填充
结果
标题
艺术家
专辑
年
插曲
挑选
找不到的结果。
结果
标题
艺术家
专辑
年
插曲
挑选
找不到的结果。
结果
标题
艺术家
专辑
年
插曲
挑选
找不到的结果。
结果
标题
艺术家
专辑
年
插曲
挑选
找不到的结果。
结果
标题
艺术家
专辑
年
插曲
挑选
找不到的结果。
结果
标题
艺术家
专辑
年
插曲
挑选
找不到的结果。
根据情节查找曲目#
插曲#
艺术家
专辑
年
挑选
正如你所见——非常冗长。我对如何获取下拉列表有一个基本的了解-虽然似乎有不止一种方法,但我尝试了以下方法:
插曲#
艺术家
专辑
年
挑选
但是我遇到的问题是从一开始就采用if
语句,并使其更加精简,这样我只需要1,它将选项选择的值和文本框的值插入SQL语句WHERE[option value]=[text value];
有人有什么建议吗?我可能忽略了一些基本的东西。在您的第一组
if
语句中,唯一改变的是查询。不需要重复所有其他内容。在您的第二组if
语句中,几十行代码中有一个单词发生了变化。这是特富尔
所以,正如你所怀疑的,这可以更有效地完成
<?php
require_once "../config.php";
require_once "../common.php";
// if it doesn't already, $options should look like this:
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
// these are safe columns to search
$columns = ["track_eps", "track_artist", "track_album", "track_year", "track_pick"];
try {
// fall back to a safe value if needed
$column = in_array($_POST["search_column"], $columns) ? $_POST["search_column"] : $columns[0];
// if it doesn't already, $dsn should include charset=utf8mb4
$connection = new PDO($dsn, $username, $password, $options);
$sql = "SELECT * FROM track_list WHERE $column = ?";
$statement = $connection->prepare($sql);
// no need for binding, just pass parameters to execute
$statement->execute([$_POST["search_text"]]);
$result = $statement->fetchAll();
} catch (\Exception $e) {
// don't show errors to the user, just pretend you got no results
$result = [];
// if you have a global exception handler, let it take over
throw $e;
}
?>
<?php if(count($result) === 0): ?>
<div class="alert">No results found for <?= escape($_POST["search_text"]) ?>.</div>
<?php else: ?>
<h2>Results</h2>
<table>
<thead>
<tr>
<th>Title</th>
<th>Artist</th>
<th>Album</th>
<th>Year</th>
<th>Episode</th>
<th>Picked By</th>
</tr>
</thead>
<tbody>
<?php foreach ($result as $row): ?>
<tr>
<td><?= escape($row["track_name"]) ?></td>
<td><?= escape($row["track_artist"]) ?></td>
<td><?= escape($row["track_album"]) ?></td>
<td><?= escape($row["track_year"]) ?></td>
<td><?= escape($row["track_eps"]) ?></td>
<td><?= escape($row["track_pick"]) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<form method="post">
<select name="search_column">
<option value="track_eps">Episode #</option>
<option value="track_artist">Artist</option>
<option value="track_album">Album</option>
<option value="track_year">Year</option>
<option value="track_pick">Picked by</option>
</select>
<input type="text" id="filter" name="search_text">
<button type="submit">Search</button>
</form>
<a href="index.php">Back to home</a>
<?php require "templates/footer.php"; ?>
100行,你会非常感激endif
和endforeach
我假设您的escape()
函数只做htmlspecialchars()
,不需要做更多的事情。因此,如果您想保存键入,为什么不调用它e()
这是一个有20年历史的参数,但您不应该出于表示的目的使用语义元素,如
。将其设置为
,给它一个类,并设置其样式。只需将select字段中作为列名动态传递的值插入WHERE子句中即可。您必须使用字符串连接,然后不能对列名使用占位符,只能对数据使用占位符。为了避免有人破坏您的SQL语句或按不应使用的列进行筛选,将允许的列名保留在数组中可能是有意义的,这样您就可以进行检查。占位符名不必以任何方式与列名匹配-因此而不是:track\u eps
,:track\u artist
等,只需使用一些通用的东西,如:value
,然后将文本字段内容绑定到它。谢谢,这有点帮助,但我想我使用相同的(或类似的)方法会使这变得更复杂到处都是标签…我必须测试一些东西。我试着按照你的建议去做,但是代码不起作用,并且给了我一个错误:SELECT*FROM track_list,其中:value=:filter SQLSTATE[HY093]:无效参数号:nu
<?php
require_once "../config.php";
require_once "../common.php";
// if it doesn't already, $options should look like this:
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
// these are safe columns to search
$columns = ["track_eps", "track_artist", "track_album", "track_year", "track_pick"];
try {
// fall back to a safe value if needed
$column = in_array($_POST["search_column"], $columns) ? $_POST["search_column"] : $columns[0];
// if it doesn't already, $dsn should include charset=utf8mb4
$connection = new PDO($dsn, $username, $password, $options);
$sql = "SELECT * FROM track_list WHERE $column = ?";
$statement = $connection->prepare($sql);
// no need for binding, just pass parameters to execute
$statement->execute([$_POST["search_text"]]);
$result = $statement->fetchAll();
} catch (\Exception $e) {
// don't show errors to the user, just pretend you got no results
$result = [];
// if you have a global exception handler, let it take over
throw $e;
}
?>
<?php if(count($result) === 0): ?>
<div class="alert">No results found for <?= escape($_POST["search_text"]) ?>.</div>
<?php else: ?>
<h2>Results</h2>
<table>
<thead>
<tr>
<th>Title</th>
<th>Artist</th>
<th>Album</th>
<th>Year</th>
<th>Episode</th>
<th>Picked By</th>
</tr>
</thead>
<tbody>
<?php foreach ($result as $row): ?>
<tr>
<td><?= escape($row["track_name"]) ?></td>
<td><?= escape($row["track_artist"]) ?></td>
<td><?= escape($row["track_album"]) ?></td>
<td><?= escape($row["track_year"]) ?></td>
<td><?= escape($row["track_eps"]) ?></td>
<td><?= escape($row["track_pick"]) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<form method="post">
<select name="search_column">
<option value="track_eps">Episode #</option>
<option value="track_artist">Artist</option>
<option value="track_album">Album</option>
<option value="track_year">Year</option>
<option value="track_pick">Picked by</option>
</select>
<input type="text" id="filter" name="search_text">
<button type="submit">Search</button>
</form>
<a href="index.php">Back to home</a>
<?php require "templates/footer.php"; ?>