Rawurlencode: примеры (PHP)
rawurlencode(string $string): stringФункция rawurlencode в PHP
Функция rawurlencode применяется для кодирования строки в соответствии со стандартом RFC 3986. Она преобразует специальные символы, кроме тире, подчеркивания, точки и буквенно-цифровых символов, в их шестнадцатеричное представление, предваряемое знаком процента (%).
Это кодирование используется для частей URL-адреса, таких как путь или параметры запроса, чтобы обеспечить корректную передачу данных, содержащих пробелы, не-ASCII символы или символы, имеющие специальное значение в URL (например, '?', '&', '=').
Функция принимает один обязательный аргумент:
- string – строка, которая подлежит кодированию.
Возвращаемое значение – закодированная строка. Если аргумент не является строкой, будет выполнен вызов __toString() для преобразования объекта в строку, в противном случае будет сгенерирована ошибка.
Примеры использования rawurlencode
echo rawurlencode('Hello World!');Hello%20World%21
$city = 'Москва';
$query = 'city=' . rawurlencode($city) . '&page=1';
echo $query;city=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0&page=1
$file = 'my document.pdf';
$path = '/download/' . rawurlencode($file);
echo $path;/download/my%20document.pdf
echo rawurlencode('a-z_A-Z.~');a-z_A-Z.~
Похожие функции в PHP
В PHP существуют другие функции для кодирования строк для использования в URL, каждая имеет свои особенности.
Функция urlencode кодирует строку для использования в query string (часть URL после знака вопроса). Основное отличие от rawurlencode заключается в кодировании пробела: urlencode преобразует пробел в знак плюс ('+'), тогда как rawurlencode использует '%20'. Для частей пути следует использовать rawurlencode.
echo urlencode('Hello World!');
echo rawurlencode('Hello World!');Hello+World%21
Hello%20World%21
Функция http_build_query генерирует строку запроса из массива, автоматически применяя urlencode к ключам и значениям. Удобна для построения сложных query string.
$data = ['city' => 'New York', 'limit' => 10];
echo http_build_query($data);city=New+York&limit=10
- rawurlencode – предпочтительна для кодирования отдельных компонентов пути URL (RFC 3986).
- urlencode – подходит для кодирования данных в query string (application/x-www-form-urlencoded).
- http_build_query – удобна для автоматического формирования query string из массива параметров.
Аналоги функции в других языках
Функция encodeURIComponent в JavaScript выполняет сходную задачу, но отличается набором незакодированных символов. Она не кодирует буквенно-цифровые символы, а также - _ . ! ~ * ' ( ). Пробел кодируется как %20.
console.log(encodeURIComponent('Hello World!'));Hello%20World%21
В модуле urllib.parse Python функция quote предоставляет схожий функционал. По умолчанию она кодирует все символы, кроме буквенно-цифровых и '_'. Пробел кодируется как %20. Параметр safe позволяет указать дополнительные символы, которые не нужно кодировать.
from urllib.parse import quote
print(quote('Hello World!'))Hello%20World%21
Функция QUOTE в MySQL предназначена для экранирования строк для использования в SQL-запросах, а не для кодирования URL. Для работы с URL в MySQL обычно используют операции со строками, но прямой встроенной функции для кодирования в стиле RFC 3986 нет.
SELECT QUOTE('Hello World!');'Hello World!'
Основное отличие от PHP rawurlencode заключается в различных стандартах кодирования и наборах незакодированных символов, что важно учитывать при межъязыковом взаимодействии.
Типичные ошибки использования
Частая ошибка – повторное применение функции к уже закодированной строке, что приводит к некорректному URL.
$str = 'data 1';
$encoded_once = rawurlencode($str); // data%201
$encoded_twice = rawurlencode($encoded_once);
echo $encoded_twice;data%25201
Символ '%' был закодирован в '%25', что делает строку нечитаемой для декодера URL.
Функция предназначена для кодирования отдельных компонентов URL, а не всего адреса целиком. Кодирование всего URL может сделать его неработоспособным.
$url = 'https://example.com/search?q=test value';
echo rawurlencode($url);https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dtest%20value
Протокол, домен, разделители '?' и '=' были закодированы, что нарушает структуру URL.
Использование rawurlencode для значения параметра, которое затем объединяется с символом '=' или '&', является корректным. Однако иногда разработчики кодируют всю пару 'ключ=значение' или ставят знак равенства внутрь функции.
// Неправильно
$param = rawurlencode('city=Москва');
echo $param;
// Правильно
$city = 'Москва';
echo 'city=' . rawurlencode($city);city%3D%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0
city=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0
Изменения в последних версиях PHP
Поведение функции rawurlencode остается стабильным на протяжении многих версий PHP. В PHP 8.0 и 8.1 не было внесено изменений, влияющих на ее работу.
Важное историческое изменение произошло в PHP 5.3.0, где функция была приведена в соответствие с RFC 3986. До этой версии пробелы кодировались как знак плюс ('+'), что соответствовало устаревшему стандарту. Начиная с PHP 5.3.0, пробел всегда кодируется как '%20'.
// Поведение до PHP 5.3.0 (условно)
// rawurlencode('Hello World!') возвращало 'Hello+World%21'
// Поведение с PHP 5.3.0 и в PHP 8
echo rawurlencode('Hello World!');Hello%20World%21
Эта особенность важна при работе с унаследованным кодом или при совместимости со старыми системами, которые могут ожидать кодирование пробела как '+'.
Расширенные примеры использования
$folder = 'Документы 2024';
$file = 'Отчёт #1.pdf';
$url_path = '/files/' . rawurlencode($folder) . '/' . rawurlencode($file);
echo $url_path;/files/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B%202024/%D0%9E%D1%82%D1%87%D1%91%D1%82%20%231.pdf
$base_url = 'https://api.example.com/search';
$params = [
'query' => 'кофе и чай',
'sort' => 'price:desc',
'limit' => 25
];
$query_string = http_build_query($params, '', '&', PHP_QUERY_RFC3986);
$full_url = $base_url . '?' . $query_string;
echo $full_url;https://api.example.com/search?query=%D0%BA%D0%BE%D1%84%D0%B5+%D0%B8+%D1%87%D0%B0%D0%B9&sort=price%3Adesc&limit=25
Использование константы PHP_QUERY_RFC3986 в http_build_query приводит к применению кодирования в стиле rawurlencode.
$data = 'Name=Surname Name';
echo 'urlencode: ' . urlencode($data) . "
";
echo 'rawurlencode: ' . rawurlencode($data);urlencode: Name%3DSurname+Name
rawurlencode: Name%3DSurname%20Name
Для application/x-www-form-urlencoded (например, отправка формы POST) ожидается кодирование пробела как '+', поэтому в данном контексте предпочтительнее urlencode.
function buildSafePath(...$segments) {
$encodedSegments = array_map('rawurlencode', $segments);
return '/' . implode('/', $encodedSegments);
}
echo buildSafePath('user files', 'category', 'my photos 2023', 'img_1.jpg');/user%20files/category/my%20photos%202023/img_1.jpg
Фрагмент URL (часть после '#') также может содержать специальные символы, которые требуют кодирования с помощью rawurlencode.
$fragment = 'section:data-table';
$url = 'https://example.com/page#' . rawurlencode($fragment);
echo $url;https://example.com/page#section%3Adata-table