$query = "SELECT :option FROM `site`.`fish` WHERE `fishid`=:fishid";
if ($stmt = $connect->prepare($query)){
$stmt->bindValue(':option', $option, PDO::PARAM_INT);
$stmt->bindValue(':fishid', $fishid, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<pre>', print_r($rows, true), '</pre>';
}
以下内容返回
Array
(
[0] => Array
(
[id] => id
)
)
我希望它返回[id] =&gt; 7 它与我的BindVaulues有关......它们不被认为是数字吗?
答案 0 :(得分:2)
准备好的陈述不可能是你想做的事。
您无法将要选择的列作为参数传递给预准备语句。该声明将评估为:
SELECT 'id' ...
什么会给你一个字符串'id'而不是列的值。
答案 1 :(得分:1)
这源于对准备语句中的占位符如何工作的常见误解:它们不是简单地用字符串替换,而是执行生成的SQL。相反,DBMS要求“准备”一个语句,它会提供一个完整的查询计划,说明它将如何执行该查询,包括它将使用哪些表和索引,无论你如何填写占位符,这都是相同的。 / p>
SELECT name FROM my_table WHERE id = :value
的计划与:value
的替换相同,但看似相似的SELECT name FROM :table WHERE id = :value
无法计划,因为DBMS不知道你实际上是哪一张表要选择。
您的表单SELECT :value FROM my_table
的查询只能计划,因为占位符代表字面值,而不是列名称 - 将:value
设置为字符串'hello'
将等效于SELECT 'hello' FROM my_table
并为结果集的每一行返回字符串'hello'
。
答案 2 :(得分:0)
列名不是SQL变量(SQL不支持在那个地方有变量),但它只是PHP中的一个字符串:
$option = (string) $option;
switch ($option)
{
case "id":
break;
default:
throw new InvalidArgumentException(
sprintf("Invalid identifier: '%s'", $option)
);
}
if (false !== strpos($option, "`"))
{
throw new InvalidArgumentException(
sprintf("Invalid column name: '%s'", $option)
);
}
$query = sprintf("SELECT `%s` FROM `site`.`fish` WHERE `fishid`=:fishid", $option);
if ($stmt = $conn->prepare($query))
{
$stmt->bindValue(':fishid', $fishid, PDO::PARAM_INT);
$stmt->execute();
...