[英]Binding parameter values - PDO Invalid parameter number
I'm writing an API class to query data. 我正在编写一个API类来查询数据。 I have a function in the class that uses a SELECT
statement to query data for a specific, hardcoded table name (ie eventLog). 我在类中有一个函数,该函数使用SELECT
语句查询数据以获取特定的硬编码表名(即eventLog)。
The query is listed below, where :value
references a paremeter passed to the function: 该查询在下面列出,其中:value
引用传递给该函数的参数:
// query
$sql = "SELECT :selectType
FROM `log` :clause
ORDER BY `:orderByColumn` :orderByClause
LIMIT :limitStart, :limitStep";
I'm trying to use PDO statements to prevent SQL injection. 我正在尝试使用PDO语句来防止SQL注入。 I have read several helpful documents regarding how to correctly write PDO statements, including bindValue / bindParam. 我已经阅读了一些有关如何正确编写PDO语句的有用文档,包括bindValue / bindParam。
Below is the full class file: 下面是完整的类文件:
<?php
// set requirements
require_once 'Database.php';
/* EventLogsAPI class
* This class is used to query data from the eventLog table, and handle other data processing
*/
class EventLogsAPI {
// set class member variables
private $connection; // database connection
private $records; // records from query
/* Constructor function
*/
public function __construct() {
// create DB object
$this->connection = new DBConnection();
}
/* Collect records function
* Get the records from this prep statement, and store them in $this->records
*
* @param object - database object
*/
public function collectRecords($prep) {
// clear records from previous query
$this->records = array();
// execute query
$prep->execute();
// for each record
while (false !== ($row = $prep->fetch(PDO::FETCH_ASSOC))) {
$this->records[] = $row;
}
}
/* getEventLogData function
* Get event log data with a optional (where) clause
*
* @param string - select state (*, distinct, etc...)
* @param string - conditional SQL clause (e.g. where ID = 2)
* @param string - order by column (e.g. user, ID, date, etc...)
* @param string - order by clause (e.g. asc, desc)
* @param integer - starting limit param (i.e. 0)
* @param integer - limit step param (i.e. 25)
* @param boolean - used to debug SQL
* @return JSON - json containing array of records
*/
public function getEventLogData($selectType, $clause, $orderByColumn, $orderByClause, $limitStart, $limitStep) {
// query
$sql = "SELECT :selectType
FROM `log` :clause
ORDER BY `:orderByColumn` :orderByClause
LIMIT :limitStart, :limitStep";
// prep the query
$prep = $this->connection->DB('log')->prepare($sql);
// for each function argument
foreach ($bind = func_get_args() as $key => $value) {
// prevent null values
if ($value == NULL) {
// set to empty strings
$bind[$key] = "";
}
// bind value
$prep->bindValue(":$bind[$key]", $bind[$key]);
// debug
echo ($key . " - " . $value . "\n");
}
// collect the records
$this->collectRecords($prep);
// return records
return json_encode($this->records);
}
}
?>
Returned network response in Chrome console: 在Chrome控制台中返回的网络响应:
0 - *
1 -
2 - date
3 - DESC
4 - 0
5 - 20
<br />
<b>Warning</b>: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in <b>EventLogsAPI.class.php</b> on line <b>32</b><br />
[]
So, based on this execution, the bound SQL query should be: 因此,基于此执行,绑定的SQL查询应为:
// query
$sql = "SELECT *
FROM `log`
ORDER BY `date` DESC
LIMIT 0, 20";
However, I'm getting the error: Invalid parameter number: parameter was not defined
. 但是,我得到了错误: Invalid parameter number: parameter was not defined
。
I have checked the following: 我检查了以下内容:
I know there are several other questions regarding this, but I have yet to find a solution to this problem. 我知道与此有关的还有其他几个问题,但是我还没有找到解决这个问题的方法。 Any help with debugging is much appreciated. 非常感谢调试方面的任何帮助。 Thank you for reading. 感谢您的阅读。
Placeholders can represent VALUES only. 占位符只能代表VALUES 。 You cannot use them for SQL keywords/identifiers. 您不能将它们用于SQL关键字/标识符。
FROM `eventLog` :clause
^--keyword/identifier
ORDER BY `:orderByColumn` :orderByClause
^--------------^--- also wrong
You also can NOT quote placeholders. 您也不能引用占位符。 Once they're quoted, they're not placeholders anymore, they're literal strings. 一旦被引用,它们就不再是占位符,它们是文字字符串。
If you want to insert that kind of thing dynmamically, you have to build the query string yourself: 如果要动态插入这种内容,则必须自己构建查询字符串:
$order_by = 'ASC':
$sql = "SELECT ... ORDER BY $order_by";
And yes, this leaves you open to potential sql injection attacks . 是的,这使您容易受到潜在的sql注入攻击 。 Placeholders are perfect for data, but they're utterly useless for many other kinds of queries. 占位符是数据的完美选择,但对于许多其他类型的查询却毫无用处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.