Pg escape string: примеры (PHP)
pg_escape_string(PgSql\Connection $connection, string $data): stringФункция pg_escape_string экранирует специальные символы в строке для безопасного использования в SQL-запросах к PostgreSQL. Её применяют при ручном формировании SQL-запросов для предотвращения инъекций. В современных приложениях предпочтительнее использовать подготовленные выражения.
Функция принимает два параметра:
- $connection (обязательный с PHP 8.0) – ресурс соединения с PostgreSQL.
- $data (обязательный) – строка, которую требуется экранировать.
До версии PHP 8.0 первый параметр был опционален. При его отсутствии использовалось последнее открытое соединение.
$conn = pg_connect("host=localhost dbname=test");
$input = "O'Reilly";
$escaped = pg_escape_string($conn, $input);
echo "INSERT INTO authors (name) VALUES ('" . $escaped . "')";
INSERT INTO authors (name) VALUES ('O''Reilly')
$conn = pg_connect("host=localhost dbname=test");
$input = "Путь: C:\\files\\new";
$escaped = pg_escape_string($conn, $input);
echo "UPDATE log SET path = '" . $escaped . "'";
UPDATE log SET path = 'Путь: C:\\\\files\\\\new'
Функция pg_escape_literal возвращает строку в кавычках, готовую для подстановки в запрос. Она автоматически добавляет кавычки.
$escaped = pg_escape_literal($conn, "O'Reilly");
echo "INSERT INTO authors (name) VALUES (" . $escaped . ")";
INSERT INTO authors (name) VALUES ('O''Reilly')
Наиболее безопасный способ. Параметры передаются отдельно от запроса, что исключает инъекции.
$result = pg_prepare($conn, "query", "INSERT INTO authors (name) VALUES ($1)");
$result = pg_execute($conn, "query", array("O'Reilly"));
Запрос выполняется без ошибок
import psycopg2
conn = psycopg2.connect("dbname=test")
cursor = conn.cursor()
cursor.execute("INSERT INTO authors (name) VALUES (%s)", ("O'Reilly",))
Библиотека использует параметризованные запросы, аналогичные подготовленным выражениям.
const query = {
text: 'INSERT INTO authors (name) VALUES ($1)',
values: ["O'Reilly"]
};
client.query(query);
Передача параметров отдельно от текста запроса.
$escaped = mysqli_real_escape_string($link, "O'Reilly");
Аналогичная функция для СУБД MySQL. Принцип работы схож, но экранируются разные символы.
$input = "test'";
$escaped = pg_escape_string($input);
Fatal error: Uncaught ArgumentCountError: pg_escape_string() expects exactly 2 arguments, 1 given
$conn = pg_connect("host=localhost dbname=test");
$data = array('key' => 'value');
$escaped = pg_escape_string($conn, $data);
Warning: pg_escape_string() expects parameter 2 to be string, array given
$conn = pg_connect("host=localhost dbname=test");
$input = "O'Reilly";
$escaped = pg_escape_string($conn, $input);
$doubleEscaped = pg_escape_string($conn, $escaped);
// В базе окажется значение O''Reilly вместо O'Reilly
Это приводит к сохранению лишних экранирующих символов.
В PHP 8.0 параметр соединения стал обязательным. Ранее функция могла использовать последнее открытое соединение по умолчанию, что иногда приводило к ошибкам.
$escaped = pg_escape_string("O'Reilly"); // Работало, если соединение было открыто
$conn = pg_connect("...");
$escaped = pg_escape_string($conn, "O'Reilly"); // Соединение обязательно$conn = pg_connect("host=localhost dbname=test");
$jsonData = json_encode(['name' => "O'Connor", 'age' => 30]);
$escapedJson = pg_escape_string($conn, $jsonData);
$query = "INSERT INTO data (json_field) VALUES ('" . $escapedJson . "')";
echo $query;
INSERT INTO data (json_field) VALUES ('{"name":"O'Connor","age":30}')
Функция корректно обрабатывает строки в кодировке соединения. Важно установить правильную кодировку при подключении.
$conn = pg_connect("host=localhost dbname=test options='--client_encoding=UTF8'");
$input = "Текст с 'апострофом' и кириллицей";
$escaped = pg_escape_string($conn, $input);
echo "INSERT INTO test (text) VALUES ('" . $escaped . "')";
INSERT INTO test (text) VALUES ('Текст с ''апострофом'' и кириллицей')
Для оператора LIKE необходимо экранировать также символы % и _.
$conn = pg_connect("host=localhost dbname=test");
$search = "100%_test";
$escapedLike = str_replace(['%', '_'], ['%', '_'], $search);
$escaped = pg_escape_string($conn, $escapedLike);
$query = "SELECT * FROM products WHERE name LIKE '%" . $escaped . "%' ESCAPE ''";
echo $query;
SELECT * FROM products WHERE name LIKE '%100%_test%' ESCAPE ''