PHP SQLSRV使用准备语句的参数排序

时间:2013-02-13 15:30:45

标签: php sql sorting prepared-statement

我无法弄清楚为什么只要我没有使用$ sort作为传入参数,排序就会起作用。以下示例适用于排序:

$sort = "quantity desc";

$sql = " with items as (
SELECT i.[item_id]
,i.[name]
,i.[value]
,i.[quantity]
,i.[available]
,isnull(r.awarded, 0) as awarded
, ROW_NUMBER() OVER(
  ORDER BY $sort
) rowNumber 
FROM [Intranet].[dbo].[Goodwell_Item] i
LEFT JOIN (
SELECT r.item_id
, COUNT(1) awarded 
from [Intranet].[dbo].[Goodwell_Reward] r
group by r.item_id
) as r
ON i.item_id = r.item_id
)
SELECT * 
FROM items 
WHERE rowNumber BETWEEN (?) and (?)
and ( (?) = '' OR (available = (?)))
";

$params = array( $pagify['startFrom'], $end, $available, $available );

$stmt = sqlsrv_query( $conn, $sql, $params );

但是,如果我将ORDER BY的行更改为:

ORDER BY (?)

并将其添加到我的$ params中,如下所示:

$params = array($sort, $pagify['startFrom'], $end, $available, $available );

然后由于某种原因被忽略了。

请告诉我如何以不允许SQL注入的方式使排序工作。

1 个答案:

答案 0 :(得分:0)

我现在正处理这个问题,在网上找不到任何帮助。

我试过了:

 $query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ";
 $result = $conn->getData($query, array($seriesID,$sortBy));

$query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY ? ?";
$result = $conn->getData($query, array($seriesID,$sortBy,$sortOrder));

在这两种情况下,我都没有错误,也没有结果。

我认为安全解决这个问题的唯一方法是在查询之前使用switch语句来手动验证可接受的值。但是,除非您只处理一个表,否则您无法知道SortBy列的可能值。

但是,如果您只是假设此时的值已经被清除,您可以使用非参数化版本,如下所示:

 $query = "SELECT * FROM {$this->view} WHERE SeriesID = ? ORDER BY " . $sortBy . " " . $sortOrder;
 $result = $conn->getData($query, array($seriesID));

我打算做的是确保在将sortBy和sortOrder传递给包含此代码的方法之前验证它。通过这种方式,我调用代码的每个地方都负责在发送数据之前验证数据。调用代码将知道它正在调用的表(或本例中的视图)的有效可能值。 (在这种情况下,我是两段代码的作者,所以我知道它是安全的。)

因此,简而言之,只需确保代码中此时的值已经清除且安全,并将该职责推高到调用此代码的代码的一级。