Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Интернет » Web-программирование » Научите пользоваться pg_escape_* функциями

Модерирует : Cheery

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

Vasya Pupkin



Мракобес
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Всем привет.  
Имеется приложение на PHP и запрос в PostgreSQL вида:

Код:
$query = "SELECT id FROM public.files WHERE counter_id = '".$channel."' AND updated_at >= '".$startDate." 08:00:00' AND updated_at <= '".$endDate." 20:00:00' ORDER BY updated_at ASC";

что преобразуется в итоговый запрос:

Код:
SELECT id FROM public.files WHERE counter_id = 'xxx' AND updated_at >= '2023-11-01 08:00:00' AND updated_at <= '2023-11-22 20:00:00' ORDER BY updated_at ASC LIMIT 1000

Все работает четко, но небезопасно.
По аналогии с mysql_real_escape_string хочу экранировать запрос. Лезем в мануал, находим функцию pg_escape_string().
Экранируем запрос:

Код:
$query_escaped = pg_escape_string("SELECT id FROM public.files WHERE counter_id = '".$channel."' AND updated_at >= '".$startDate." 08:00:00' AND updated_at <= '".$endDate." 20:00:00' ORDER BY updated_at ASC LIMIT 1000");

Запрос приобретает вид:

Код:
 
SELECT id FROM public.files WHERE counter_id = ''6890f91a-7bb7-4a18-88a4-062c6aa1f920'' AND updated_at >= ''2023-11-01 08:00:00'' AND updated_at <= ''2023-11-22 20:00:00'' ORDER BY updated_at ASC LIMIT 1000
 

после чего PHP сразу дает нам отлуп:

Цитата:
Warning: pg_query(): Query failed: ERROR: syntax error at or near "6890" LINE 1: SELECT id FROM public.files WHERE counter_id = ''6890f91a-7b... ^

 
Я сначала не обратил внимание, подумал, что при экранировании кавычки превратились в двойные, однако, как оказалось, функция продублировала все мои одинарные кавычки, что ожидаемо привело к ошибке.
Окей, может попробуем двойные кавычки в запросе вместо одинарных? Заменяем и экранируем, получая такой код:

Код:
 
$query_escaped = pg_escape_string("SELECT id FROM public.files WHERE counter_id = \"".$channel."\" AND updated_at >= \"".$startDate." 08:00:00\" AND updated_at <= \"".$endDate." 20:00:00\" ORDER BY updated_at ASC LIMIT 1000");
 

на что получаем другой отлуп:

Цитата:
Warning: pg_query(): Query failed: ERROR: column "6890f91a-7bb7-4a18-88a4-062c6aa1f920" does not exist LINE 1: SELECT id FROM public.files WHERE counter_id = "6890f91a-7bb... ^

Ладно, бог с ним, может функция эта какая-то нерабочая? Тем более, что в мануале черным по белому написано, что лучше использовать функцию pg_escape_literal(). Ок, ею и воспользуемся.
Меняем функцию и после экранирования видим такой запрос:

Код:
 
'SELECT id FROM public.files WHERE counter_id = ''6890f91a-7bb7-4a18-88a4-062c6aa1f920'' AND updated_at >= ''2023-11-01 08:00:00'' AND updated_at <= ''2023-11-22 20:00:00'' ORDER BY updated_at ASC LIMIT 1000'

что на выходе дает уже третий отлуп:

Цитата:
Warning: pg_query(): Query failed: ERROR: syntax error at or near "'SELECT id FROM public.files WHERE counter_id = ''6890f91a-7bb7-4a18-88a4-062c6aa1f920'' AND updated_at >= ''2023-11-01 08:00:00'' AND updated_at <= ''2023-11-22 20:00:00'' ORDER BY updated_at ASC LIMIT 1000'" LINE 1: 'SELECT id FROM public.files WHERE counter_id = ''6890f91a-7... ^  

Обратите внимание, интерпретатор споткнулся сразу же, вначале, потому что теперь весь запрос обернут в одинарные кавычки, которые так не нравятся PHP.
Так как правильно пользоваться этими функциями? Что я делаю не так? В интернете, на удивление, скудная и одинаковая информация по этой теме. Спасибо!

----------
я не люблю людей

Всего записей: 7067 | Зарегистр. 24-02-2001 | Отправлено: 13:04 27-11-2023
Mavrikii

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Vasya Pupkin
 
Санировать нужно только подставляемые значения, а не весь запрос целиком. В этом и смысл функции - экранировать значение так, чтобы оно не могло 'закрыть' начавшийся запрос и вставить какой то свой (читать об SQL Injection) или просто привести к ошибке.
 
Насчет кавычки- очевидно же, что как только встречаются те кавычки, которыми строка открыта, то она закрывается, остальное идет вне строки. Нужно добавлять экранирование для кавычек того же типа.
$str = 'другая " - ок, а вот такая же \' требует экранирования';
 
Есть и другой способ (ниже оба варианта)

Код:
<?php
// Connect to a database named "mary"
$dbconn = pg_connect("dbname=mary");
 
// Find all shops named Joe's Widgets. Note that it is not necessary to
// escape "Joe's Widgets"
$result = pg_query_params($dbconn, 'SELECT * FROM shops WHERE name = $1', array("Joe's Widgets"));
 
// Compare against just using pg_query
$str = pg_escape_string("Joe's Widgets");
$result = pg_query($dbconn, "SELECT * FROM shops WHERE name = '{$str}'");

Всего записей: 15139 | Зарегистр. 20-09-2014 | Отправлено: 16:00 27-11-2023 | Исправлено: Mavrikii, 16:03 27-11-2023
Vasya Pupkin



Мракобес
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Санировать нужно только подставляемые значения, а не весь запрос целиком.  

Mavrikii, ларчик просто открывался. Все взлетело, спасибо!


----------
я не люблю людей

Всего записей: 7067 | Зарегистр. 24-02-2001 | Отправлено: 15:21 29-11-2023
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Интернет » Web-программирование » Научите пользоваться pg_escape_* функциями


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru