mysqli_stmt_bind_param () данные не предоставляются, когда знак вопроса является частью запроса - PullRequest
0 голосов
/ 28 января 2020

Подобные вопросы задавались много раз, но после прочтения почти каждого из них в течение более 5 часов я не нашел подходящего ответа для своей проблемы.

Я не опыт php / mysql разработчик, но я справился с подобными ситуациями с помощью mysqli_stmt_bind_param () fun c.

Вот запрос:

$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" : [{...},{...}]
}

Ошибка: Неустранимая ошибка : Uncaught mysqli_sql_exception: Нет данных для параметров в подготовленном операторе

Я уже сделал подобные запросы с большим количеством параметров, без каких-либо ошибок: однако я впервые использую JSON_EXTRACT fun c из mysql.

Я считаю, что ошибка вызвана $. который не избежал правильно. Заменяемые параметры ссылаются на одну и ту же переменную $ id, которая является целым числом и используется для интерполяции строк в первом случае («Категория 1») и в качестве числа после предложения WHERE.

Рассмотрим что, не используя mysqli_stmt_bind_param, тот же самый запрос на phpmyadmin возвращает то, что я хочу, но это откроет мой код для mysql инъекций, которых я хочу избежать.

Кроме того, обратите внимание, что если я передам только один В качестве параметра функции сценарий выполняется (с неверными результатами), например, если в какой-то момент запрос усекается ... я правильно экранировал каждую кавычку и даже пытался использовать двойные кавычки, но ошибка всегда одинакова.
Любая подсказка о том, как предотвратить инъекцию и достичь результата, будет высоко оценена, потому что я действительно не могу понять это самостоятельно.
Спасибо

Ответы [ 2 ]

3 голосов
/ 28 января 2020

У вас есть два параметра в вызове 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 = ?';
1 голос
/ 28 января 2020

Заполнитель может представлять полный литерал данных только . Проще говоря - все, что вы написали бы в кавычках (или число). Так что это не должно быть '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);
...