简体   繁体   English

SQL串联搜索选项的替代方法?

[英]An alternative to SQL concatenation for search options?

I'm a novice programmer, and I've inherited an application designed and built by a person who has now left the company. 我是一个新手程序员,并且继承了一个由现在离开公司的人设计和构建的应用程序。 It's done in PHP and SQL Server 2008R2. 它是在PHP和SQL Server 2008R2中完成的。 In this application, there's a page with a table displaying a list of items, populated from the database, with some options for filters in a sidebar - search by ID, keyword, date etc. This table is populated by a mammoth query, and the filters are applied by concatenating them into said query. 在此应用程序中,有一个页面,其中包含一个表,该表显示从数据库中填充的项目列表,并在边栏中提供了一些过滤器选项-按ID,关键字,日期等进行搜索。该表由一个庞大的查询填充,并且通过将过滤器串联到所述查询中来应用过滤器。 For example, if someone wanted item #131: 例如,如果有人想要商品#131:

$filterString = "Item.itemID = 131";
$filter = " AND " . $filterString;

SELECT ...
FROM ...
WHERE...
$filter

The filter is included on the end of the URL of the search page. 过滤器包含在搜索页面URL的末尾。 This isn't great, and I'm fairly sure there are some SQL injection vulnerabilities as a result, but it is extremely flexible - the filter string is created before it's concatentated, and can have lots of different conditions: Eg$filterString could be "condition AND condition AND coindtion OR condition". 这不是很好,并且我可以肯定地确定会有一些SQL注入漏洞,但是它非常灵活-过滤字符串在连接之前创建,并且可以有很多不同的条件:例如,$ g “条件和条件与条件或条件”。

I've been looking into Stored Procedures, as a better way to counter the issue of SQL Injection, but I haven't had any luck working out how to replicate this same level of flexibility. 我一直在研究存储过程,这是解决SQL注入问题的一种更好的方法,但是我没有运气找出如何复制这种相同级别的灵活性。 I don't know ahead of time which of the filters (if any) will be selected. 我不知道会提前选择哪个过滤器(如果有)。

Is there something I'm missing? 有什么我想念的吗?

Use either Mysqli or PDO which support prepared/parameterized queries to battle sql injection. 使用支持预准备/参数化查询的Mysqli或PDO对抗SQL注入。 In PDO this could look something like this 在PDO中,可能看起来像这样

$conditions = '';
$params = array();

if(isset($form->age)) {
  $conditions .= ' AND user.age > ?'
  $params[] = $form->age;
}

if(isset($form->brand)) {
  $conditions .= ' AND car.brand = ?'
  $params[] = $form->brand;
}

$sql = "
  SELECT ...
  FROM ...
  LEFT ...
  WHERE $conditions
  ";

$sth = $dbh->prepare($sql);
$sth->execute($params);

$result = $sth->fetchAll();

From the manual: 从手册中:

Calling PDO::prepare() and PDOStatement::execute() for statements that will be issued multiple times with different parameter values optimizes the performance of your application by allowing the driver to negotiate client and/or server side caching of the query plan and meta information, and helps to prevent SQL injection attacks by eliminating the need to manually quote the parameters. 为将使用不同参数值多次发出的语句调用PDO :: prepare()和PDOStatement :: execute()可以使驱动程序协商查询计划的客户端和/或服务器端缓存,从而优化应用程序的性能,并且元信息,并消除了手动引用参数的需要,从而有助于防止SQL注入攻击。

http://no1.php.net/manual/en/pdo.prepare.php http://no1.php.net/manual/zh/pdo.prepare.php

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM