【问题标题】:Is it possible to use bind_param for ORDER BY? [duplicate]是否可以将 bind_param 用于 ORDER BY? [复制]
【发布时间】:2012-08-18 18:07:21
【问题描述】:

在我的脑海中,我有一个类似这样的查询:

$sort = isset($sort) ? sanitize($_sort) : 'id';

if ($result = $link->prepare("
    SELECT id, price
    FROM items
    ORDER BY ?
"))
{
    $result->bind_param("s", $sort);
    $result->execute();
    etc...
}

当我在不设置排序变量的情况下运行此代码块时,它运行时不会出现与在 ORDER BY 子句中使用 ? 相关的错误,并且结果集显示在看似带有“ORDER”的结果集中按 ID”。

如果我将排序变量设置为“price ASC”之类的值,我仍然会得到一个似乎是“ORDER BY id”而不是“ORDER BY price ASC”的结果集。

现在,如果我更改代码并像这样运行它:

$sort = isset($sort) ? sanitize($_sort) : 'id';

if ($result = $link->prepare("
    SELECT id, price
    FROM items
    ORDER BY $sort
"))
{
    $result->execute();
    etc...
}

它运行正确,结果集与我在 phpMyAdmin 中的查询相同。

这里到底发生了什么以及为什么查询没有按照我最初使用 bind_param 的意图运行。

在我看来,它应该可以工作,因为不会出现与此类使用相关的错误......但实际上它似乎不适用于 ORDER BY 子句。几乎就像它在运行 bind_param 时没有翻译排序变量一样。

编辑:

对于任何感兴趣的人-

if (isset($sort))
{
    $acceptableSortValues = array('name', 'price ASC', 'price DESC');
    $sort = sanitize($sort);
    if (!in_array($sort, $acceptableSortValues))
    {
        $sort = 'name';
    }   
}
else
{
    $sort = 'name';
}

if ($result = $link->prepare("
    SELECT name, price
    FROM items
    ORDER BY $sort
"))
{
    $result->execute();
    etc...
}

【问题讨论】:

    标签: php mysqli sql-order-by prepared-statement bindparam


    【解决方案1】:

    只有 data 可以与占位符绑定。

    列/表名是模式的一部分,不能绑定。 (它产生“奇怪的结果”而不是简单地产生错误的事实是实现的一个特点。)

    我建议使用列名和受控字符串插值的白名单

    【讨论】:

    • 您好,感谢您的评论。我认为这是我的推理有问题。您能否进一步详细说明您的建议是什么,因为我对 PHP 的一般知识不是很好。我已经自学了我所知道的一切,但似乎我不知道这样的事情:)
    • @BlackberryFan 这不是 PHP 的说法。这就是占位符在 [我所知道的] SQL 实现中的工作方式。它们允许用不同的数据替换相同的形状查询(相同的列、表、相同的连接、相同的 where 运算符等),但不允许更改查询的形状。虽然一个简单的实现可以在内部调用 mysql_real_escape_string 之后执行替换,但这会导致更多问题,因为 ORDER BY 'some escaped data' 是 .. 充其量是奇怪的,而且通常是不正确的。
    • 好的,非常感谢,这确实很有意义......但我不明白的是你在这里建议的工作。我了解第二个示例中涉及的问题,这就是为什么我一直试图将查询转换为准备好的语句。我想我要问的是处理此类事情的首选方法是什么? (用蹩脚的话:))
    • @BlackberryFan 使用字符串插值,如上一个帖子示例中所做的那样(如果仍有 数据,则使用占位符正常绑定)。在为列名(和仅列名)进行字符串插值时,我建议使用白名单。也就是说,对于$sort接受"id""price"的值,而拒绝任何其他值——这个白名单是 i> 列的消毒过程。使用“接受的列名”数组可以使测试变得简单。
    • 啊!!!哦,我的天哪,这就像理解的爆炸:)这确实很有意义,因为我以前实际上使用过这样的东西,但从来没有完全用过这些术语......它们对我来说......“东西”。但真的非常感谢您的意见!你说对了!
    猜你喜欢
    • 1970-01-01
    • 2011-08-14
    • 2013-10-06
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2017-11-02
    • 2015-05-01
    • 1970-01-01
    相关资源
    最近更新 更多