使用 html 下拉列表输入的 php 中的 SQL 查询

Posted

技术标签:

【中文标题】使用 html 下拉列表输入的 php 中的 SQL 查询【英文标题】:SQL query in php with input from html dropdown 【发布时间】:2020-03-14 22:38:38 【问题描述】:

好的,我想做的是为一个项目制作一个查询评估工具。我将用户输入作为 php 变量获取并在我的查询中使用它,所以就像用户正在提交查询一样。我正在使用 mysqli

我目前正在处理我的查询

$sql = "SELECT * FROM `idk` where  `alias` = '".$s."'"; 

我从下面的表格中获取值

$s = $_GET['val'];
<select name="selector" id = "selector">
        <option value="">Select a criteria:</option>
        <option value="0">id</option>
        <option value="1">name</option>
        <option value="2">email</option>
        <option value="3">alias</option>
        <option value="4">position</option>

我想知道是否可以为 where 子句条件 (=,!=) 添加用户输入并像获取列的值一样获取它,而不是对其进行硬编码。

请记住,这是针对 uni 项目的,没有人会使用它或删除我的数据库,但我们将不胜感激任何安全建议。

【问题讨论】:

先学会使用参数化查询。 问题是什么 如果我可以使用 php 变量而不是实际的 = 或 LIKE 您在这里要求或尝试做什么非常不清楚。您是否在问是否可以在查询中使用 PHP 变量来形成 where 条件?如果是这样,提供的select 对其有何影响?表的结构是什么?一般来说,当用户选择其中一个选项并提交表单时应该发生什么? @El_Vanja 我编辑了这个问题,很抱歉不清楚。我对此真的很陌生,这让我很困惑。如果我问错问题或以奇怪的方式,我很抱歉。任何帮助将不胜感激。是的,我试图让用户提交 where 子句条件,我想知道我是否可以使用用户输入来制作整个 where 子句 【参考方案1】:

最短的答案:是的。你可以控制一切。实现这一点所需要做的就是在表单中添加另一个选择元素,让用户控制比较值的方式。我将使用一个简化的示例。

如果您有用户值的输入:

<input type="number" name="age" value="" />

在它之前添加一个选择字段:

<select name="age_comparison">
    <option value="equal">equal to</option>
    <option value="not_equal">not equal to</option>
    <option value="less_than">less than</option>
    <option value="greater_than">greater than</option>
</select>
<input type="number" name="age" value="" />

注意:该位置与处理无关 - 根本没有。我只是认为,如果用户像阅读现实生活中的一段文字一样阅读您的页面,那将是一种更好的用户体验。这意味着当输入稍后出现时,它将读取为“年龄大于 X”,如果您将输入放在首位,则它比“年龄 X,大于”更好。

出于同样的原因(更好的用户体验),我倾向于用读起来更像人类的东西来标记选项,因此“等于”而不是“等于”。但是我从选项值中省略了它,因为它没有向代码添加任何有价值的信息(“等于”作为参数值讲述了整个故事)。

然后,在提交表单后,您可以检测用户的选择并相应地构建查询字符串:

if (isset($_GET['age'])) 
    $age = $_GET['age'];

if (isset($_GET['age_comparison'])) 
    switch ($_GET['age_comparison']) 
        case 'equal':
            $ageComparison = '=';
            break;
        case 'not_equal':
            $ageComparison = '!=';
            break;
        case 'less_than':
            $ageComparison = '<';
            break;
        case 'greater_than':
            $ageComparison = '>';
            break;
    

// if we have all the parameters, we can query the database
if (isset($age) && isset($ageComparison)) 
    // the following line is very unsafe - we'll be on that in a minute
    $queryString = 'SELECT * FROM students WHERE age '.$ageComparison.$age;
    ...

注意:我使用了$_GET,因为您在问题中使用了它。如果您要在表单中包含多个参数,我建议您宁愿使用post 方法,并避免将一大堆参数添加到页面的 url。您的表单值将位于相同的键下,仅在 $_POST 变量中。另外,当您使用post 时,检测是否设置了提交的名称就足够了——如果是,则保证来自同一表单的其余输入也存在。使用get,您必须单独检查每个参数。

所以你有它。带有变量比较运算符的查询。

但是

我们还没有完成。有一些不好的做法需要改掉,也有一些好的做法需要学习。

首先,永远不要通过直接插入参数来构建查询:

$sql = "SELECT * FROM `idk` where  `alias` = '".$s."'";

这让您对SQL injection 敞开心扉。您应该改用prepared statements。准备好的语句具有内置的保护机制,还可以满足您的所有引用需求(这意味着您不必手动在字符串参数周围放置 uote 标记)。所以你这样做:

// the question mark means we'll be adding a parameter in that position
$queryString = 'SELECT * FROM students WHERE age '.$ageComparison.' ?';
// here I assume you have mysqli statement ready
// you can see an example about creating one in the link about prepared statements
$statement->prepare($queryString);
$statement->bindParam('i', $age);

你可能会说“但是等一下!你只是添加了比较运算符直接!这不是很危险吗?” - 不,因为它不是直接来自用户。我们在 switch 语句中决定了它的值,这意味着我们接受用户的输入(可能会受到损害)并将其转换为 我们控制的值。用户无法决定 switch 语句的结果,我们可以。因此,直接将其连接到查询字符串中是安全的,因为我们知道我们已经定义了一些安全值。

说到 switch 语句,这里也需要改进。如果我们在select 中添加另一个选项,但我们忘记在 switch 语句中添加它怎么办?还是恶意用户损害了正在发送的选项的价值?我们最终会得到一个错误,因为那时不会匹配 switch 中的任何情况(我们放在那里的 4 之外的值的情况没有定义),因此变量$ageComparison 将永远不会被创建,我们将永远不要执行查询,因为我们的 if 条件会失败。那么我们该如何解决呢?我们添加一个默认案例(当没有案例匹配时默认执行):

// remainder of statement cut for length
    ...
    case 'greater_than':
        $queryComparison = '>';
        break;
    default:
        throw new Exception('Unsupported value for age comparison: '.$ageComparison);

异常在未处理时会停止执行(正确的术语是caught),但如果您想自己探索该主题,我会留给您(对于初学者来说似乎有点多) ,而且这里已经有相当多的文字了)。

【讨论】:

我现在明白了。非常感谢您抽出时间来做这件事。还要感谢您解释准备好的陈述。我非常感谢它真的很有帮助 这适用于我的 ID,但不适用于姓名之类的东西。我是否必须修改内容才能使用字符串? 是的,当你绑定一个参数时,你必须告诉函数类型是什么。每当您不确定某事时,第一步是咨询documentation。

以上是关于使用 html 下拉列表输入的 php 中的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

PHP 和 HTML 中的相关下拉列表

html做网页,关于日期下拉列表框的问题

将下拉列表中的第一个值设置为 php 中的默认值

带有“数量”下拉列表的 PHP 表单可将输入的数据行数插入表单

带有分层邻接模型MySql和PHP的缩进HTML下拉列表

从MySQL加载数据并使用jQuery Mobile,PHP选择填充下拉列表