mysqli_stmt_bind_param() 当问号是查询的一部分时未提供数据
mysqli_stmt_bind_param() data not supplied when a question mark is a part of the query
类似的问题已经被问过很多次了,但是在阅读了几乎所有这些问题超过 5 个小时之后,我还没有找到适合我的问题的答案。
我不是经验丰富的 php / mysql 开发人员,但我使用 mysqli_stmt_bind_param() 函数处理过类似情况。
这里是查询:
$query = 'SELECT Recipes.* , Categories.* FROM `Recipes` JOIN `Categories` ON JSON_EXTRACT(Recipes.category, \'$.category\') = \'Category ?\' WHERE Categories.category = ?';
我使用这个 php 代码:
if ($stmt = mysqli_prepare($dbManager->getDBInstance(), $query)){
mysqli_stmt_bind_param($stmt,"ii", $id, $id);
}
因为我在客户端有一个模型,例如:
{
"category" : "...",
"recipes" : [{...},{...}]
}
错误是:致命错误:未捕获mysqli_sql_exception:没有为准备好的语句中的参数提供数据
我已经使用更多参数进行了类似的查询,没有任何错误:但是,这是我第一次使用 mysql 中的 JSON_EXTRACT 函数。
我认为错误是由 $.没有正确转义。要替换的参数引用同一个变量 $id,它是一个整数,在第一种情况下用于字符串插值 ('Category 1'),在 WHERE 子句后用作数字。
考虑一下,通过不使用 mysqli_stmt_bind_param,对 phpmyadmin returns 的相同查询是我想要的,但这会打开我的代码以进行 mysql 注入,我想避免。
此外,请注意,如果我只将一个参数传递给函数,脚本就会执行(结果错误),就像查询在某个时候被截断一样......我正确地转义了每个单引号,甚至尝试使用双引号,但错误始终相同。
任何关于如何防止注入和实现结果的提示将不胜感激,因为我真的无法自己弄清楚。
谢谢
您在 mysqli_stmt_bind_param()
的调用中有两个参数,但 $query
中只有一个占位符。第一个 ?
在引号内,因此按字面意思处理,而不是占位符。
您可以使用 CONCAT()
将字符串文字与占位符连接起来,因此将其更改为:
$query = '
SELECT Recipes.* , Categories.*
FROM `Recipes`
JOIN `Categories` ON JSON_EXTRACT(Recipes.category, \'$.category\') = CONCAT(\'Category \', ?)
WHERE Categories.category = ?';
占位符只能表示完整的数据文字。简单来说——任何你会用引号(或数字)写的东西。所以它不应该是 'Category ?'
而只是 ?
类别可以在 PHP.
中连接
$query = 'SELECT * FROM `Recipes` JOIN `Categories` ON
JSON_EXTRACT(Recipes.category, \'$.category\') = ?
WHERE Categories.category = ?';
$stmt = mysqli_prepare($dbManager->getDBInstance(), $query);
$category = "Category $id";
mysqli_stmt_bind_param($stmt,"si", $category, $id);
类似的问题已经被问过很多次了,但是在阅读了几乎所有这些问题超过 5 个小时之后,我还没有找到适合我的问题的答案。
我不是经验丰富的 php / mysql 开发人员,但我使用 mysqli_stmt_bind_param() 函数处理过类似情况。
这里是查询:
$query = 'SELECT Recipes.* , Categories.* FROM `Recipes` JOIN `Categories` ON JSON_EXTRACT(Recipes.category, \'$.category\') = \'Category ?\' WHERE Categories.category = ?';
我使用这个 php 代码:
if ($stmt = mysqli_prepare($dbManager->getDBInstance(), $query)){
mysqli_stmt_bind_param($stmt,"ii", $id, $id);
}
因为我在客户端有一个模型,例如:
{
"category" : "...",
"recipes" : [{...},{...}]
}
错误是:致命错误:未捕获mysqli_sql_exception:没有为准备好的语句中的参数提供数据
我已经使用更多参数进行了类似的查询,没有任何错误:但是,这是我第一次使用 mysql 中的 JSON_EXTRACT 函数。
我认为错误是由 $.没有正确转义。要替换的参数引用同一个变量 $id,它是一个整数,在第一种情况下用于字符串插值 ('Category 1'),在 WHERE 子句后用作数字。
考虑一下,通过不使用 mysqli_stmt_bind_param,对 phpmyadmin returns 的相同查询是我想要的,但这会打开我的代码以进行 mysql 注入,我想避免。
此外,请注意,如果我只将一个参数传递给函数,脚本就会执行(结果错误),就像查询在某个时候被截断一样......我正确地转义了每个单引号,甚至尝试使用双引号,但错误始终相同。
任何关于如何防止注入和实现结果的提示将不胜感激,因为我真的无法自己弄清楚。
谢谢
您在 mysqli_stmt_bind_param()
的调用中有两个参数,但 $query
中只有一个占位符。第一个 ?
在引号内,因此按字面意思处理,而不是占位符。
您可以使用 CONCAT()
将字符串文字与占位符连接起来,因此将其更改为:
$query = '
SELECT Recipes.* , Categories.*
FROM `Recipes`
JOIN `Categories` ON JSON_EXTRACT(Recipes.category, \'$.category\') = CONCAT(\'Category \', ?)
WHERE Categories.category = ?';
占位符只能表示完整的数据文字。简单来说——任何你会用引号(或数字)写的东西。所以它不应该是 'Category ?'
而只是 ?
类别可以在 PHP.
$query = 'SELECT * FROM `Recipes` JOIN `Categories` ON
JSON_EXTRACT(Recipes.category, \'$.category\') = ?
WHERE Categories.category = ?';
$stmt = mysqli_prepare($dbManager->getDBInstance(), $query);
$category = "Category $id";
mysqli_stmt_bind_param($stmt,"si", $category, $id);