swaro
@swaro
Nice code - awesome bugs

Почему не получается использовать плейсхолдер внутри JSON (RedBeanPHP)?

Здравствуйте! У меня есть задача: проверить, апвоутил ли "$username" запись с идентификатором "$id". Для этого я написал следующее (БД PostgreSQL):
$foo = R::getRow('SELECT "votes"::jsonb @> \'{"upvote":[":username"]}\'::jsonb AS "is_upvoted" FROM "pages" WHERE "id" = :id', [":id"=>$id,":username"=>$username];

Проблема в том, что я получаю ошибку HY093 (судя по гуглу, эта ошибка появляется при неудачах с плейсхолдерами)

Потом я пытался экранировать кавычки внутри JSON строки, так, чтобы получилось:
\'{\"upvote"\:[\":username\"]}\'
Результат тот же.

После я пытался вообще убрать кавычки возле ":username", так, чтобы было:
\'{"upvote"\:[:username]}\'
Но получаю всю ту же ошибку.

Но, когда я не использую плейсхолдер в месте ":username", т.е, когда код выглядит так:
$foo = R::getRow('SELECT "votes"::jsonb @> \'{"upvote":["'.$username.'"]}\'::jsonb AS "is_upvoted" FROM "pages" WHERE "id" = :id', [":id"=>$id];

операция происходит успешно и я получаю свой результат. Конечно, сейчас я использую свою, проверенную переменную, но потом я хочу использовать подобный запрос для пользовательского поиска, и понимаю, что это небезопасно, поэтому хочу попросить здесь помощи: в чем причина и как это можно решить?
  • Вопрос задан
  • 59 просмотров
Решения вопроса 1
swaro
@swaro Автор вопроса
Nice code - awesome bugs
Решение!
Надо было не составлять JSON вручную и заполнять плейсхолдеры в нем через RB, а создать массив со структурой нужного JSON, и для заполнения использовать уже готовый массив/переменную.

Вот, как это сделал я:

$username_in_array = array('upvote' => array($username));
$username_in_json = json_encode($username_in_array);
$is_upvoted = R::getRow('SELECT "votes"::jsonb @> :username::jsonb AS "is_upvoted" FROM "pages" WHERE "id" = :id', [":id"=>$id,":username"=>$username_in_json];

Запрос принимает следующий вид:
SELECT "votes"::jsonb @> '{"upvote":["admin"]}'::jsonb AS "is_upvoted" FROM "pages" WHERE "id" = 1

Проверено - работает.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
dimonchik2013
@dimonchik2013
...а ну-ка пыль сдуй отсюда...
попробуй '' (дважды одинарная) вместо \'
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы