Как экранировать кавычки в php
Перейти к содержимому

Как экранировать кавычки в php

  • автор:

addslashes

Небольшой пример использования функции addslashes() для экранирования вышеперечисленных символов:

Иногда функцию addslashes() некорректно пытаются использовать для предотвращения SQL-инъекций. Не делайте так. Вместо неё используйте подготовленные запросы или функции экранирования соответствующих модулей работы с базами данных.

Список параметров

Возвращаемые значения

Возвращает экранируемую строку.

Примеры

Пример #1 Пример использования addslashes()

<?php
$str = «Ваше имя O’Reilly?» ;

// выводит: Ваше имя O\’Reilly?
echo addslashes ( $str );
?>

Смотрите также

  • stripcslashes() — Удаляет экранирование символов, произведённое функцией addcslashes
  • stripslashes() — Удаляет экранирование символов
  • addcslashes() — Экранирует строку слешами в стиле языка C
  • htmlspecialchars() — Преобразует специальные символы в HTML-сущности
  • quotemeta() — Экранирует специальные символы
  • get_magic_quotes_gpc() — Получение текущего значения настройки конфигурации magic_quotes_gpc

User Contributed Notes 19 notes

Never use addslashes function to escape values you are going to send to mysql. use mysql_real_escape_string or pg_escape at least if you are not using prepared queries yet.

keep in mind that single quote is not the only special character that can break your sql query. and quotes are the only thing which addslashes care.

To output a PHP variable to Javascript, use json_encode().

$var = «He said \»Hello O’Reilly\» & disappeared.\nNext line. » ;
echo «alert(» . json_encode ( $var ). «);\n» ;

?>

Output:
alert(«He said \»Hello O’Reilly\» & disappeared.\nNext line. «) ;

Beware of using addslashes() on input to the serialize() function. serialize() stores strings with their length; the length must match the stored string or unserialize() will fail.

Such a mismatch can occur if you serialize the result of addslashes() and store it in a database; some databases (definitely including PostgreSQL) automagically strip backslashes from «special» chars in SELECT results, causing the returned string to be shorter than it was when it was serialized.

In other words, do this.

<?php
$string = «O’Reilly» ;
$ser = serialize ( $string ); # safe — won’t count the slash
$result = addslashes ( $ser );
?>

. and not this.

<?php
$string = «O’Reilly» ;
$add = addslashes ( $string ); # RISKY! — will count the slash
$result = serialize ( $add );
?>

In both cases, a backslash will be added after the apostrophe in «O’Reilly»; only in the second case will the backslash be included in the string length as recorded by serialize().

[Note to the maintainers: You may, at your option, want to link this note to serialize() as well as to addslashes(). I’ll refrain from doing such cross-posting myself. ]

For PHP 7.3.* use FILTER_SANITIZE_ADD_SLASHES.

<?php
$str = «Is your name O’Reilly?» ;
$strWithSlashes = filter_var ( $str , FILTER_SANITIZE_ADD_SLASHES );

// Outputs: Is your name O\’Reilly?
echo $strWithSlashes ;

If all you want to do is quote a string as you would normally do in PHP (for example, when returning an Ajax result, inside a json string value, or when building a URL with args), don’t use addslashes (you don’t want both » and ‘ escaped at the same time). Instead, just use this function:

<?php
function Quote ( $Str ) // Double-quoting only
<
$Str = str_replace ( ‘»‘ , ‘\»‘ , $Str );
return ‘»‘ . $Str . ‘»‘ ;
> // Quote
?>

Modify this easily to get a single-quoting function.

This function is deprecated in PHP 4.0, according to this article:

Also, it is worth mentioning that PostgreSQL will soon start to block queries involving escaped single quotes using \ as the escape character, for some cases, which depends on the string’s encoding. The standard way to escape quotes in SQL (not all SQL databases, mind you) is by changing single quotes into two single quotes (e.g, ‘ ‘ ‘ becomes ‘ » ‘ for queries).

You should look into other ways for escaping strings, such as «mysql_real_escape_string» (see the comment below), and other such database specific escape functions.

Be careful on whether you use double or single quotes when creating the string to be escaped:

$test = ‘This is one line\r\nand this is another\r\nand this line has\ta tab’;

echo $test;
echo «\r\n\r\n»;
echo addslashes($test);

$test = «This is one line\r\nand this is another\r\nand this line has\ta tab»;

echo $test;
echo «\r\n\r\n»;
echo addslashes($test);

Addslashes is *never* the right answer, it’s (ab)use can lead to security exploits!

if you need to escape HTML, it’s (unfortunately)
<?php
echo htmlentities ( $html , ENT_QUOTES | ENT_SUBSTITUTE | ENT_DISALLOWED );
?>
if you need to quote shell arguments, it’s
<?php
$cmd .= » —file keyword»>. escapeshellarg ( $arg );
?>
if you need to quote SQL strings it’s
<?php
$sql .= «WHERE col = ‘» . $mysqli -> real_escape_string ( $str ). «‘» ;
?>
or
<?php
$sql .= «WHERE col keyword»>. $pdo -> quote ( $str );
?>
if you need to quote javascript/json strings its
<?php
let str = <?= json_encode ( $str , JSON_THROW_ON_ERROR ); ?> ;
?>

if you need to quote a string in xpath it’s
<?php
//based on https://stackoverflow.com/a/1352556/1067003
function xpath_quote ( string $value ): string <
if( false === strpos ( $value , ‘»‘ )) <
return ‘»‘ . $value . ‘»‘ ;
>
if( false === strpos ( $value , ‘\» )) <
return ‘\» . $value . ‘\» ;
>
// if the value contains both single and double quotes, construct an
// expression that concatenates all non-double-quote substrings with
// the quotes, e.g.:
//
// concat(«‘foo'», ‘»‘, «bar»)
$sb = ‘concat(‘ ;
$substrings = explode ( ‘»‘ , $value );
for( $i = 0 ; $i < count ( $substrings );++ $i ) <
$needComma =( $i > 0 );
if( $substrings [ $i ]!== » ) <
if( $i > 0 ) <
$sb .= ‘, ‘ ;
>
$sb .= ‘»‘ . $substrings [ $i ]. ‘»‘ ;
$needComma = true ;
>
if( $i < ( count ( $substrings ) — 1 )) <
if( $needComma ) <
$sb .= ‘, ‘ ;
>
$sb .= «‘\»‘» ;
>
>
$sb .= ‘)’ ;
return $sb ;
>
$xp -> query ( ‘/catalog/items/item[title=’ . xpath_quote ( $var ). ‘]’ );
?>
if you need to quote strings in CSS its
<?php
// CSS escape code ripped from Zend Framework ( https://github.com/zendframework/zf2/blob/master/library/Zend/Escaper/Escaper.php )
function css_escape_string ( $string )
<
$cssMatcher = function ( $matches ) <
$chr = $matches [ 0 ];
if ( strlen ( $chr ) == 1 ) <
$ord = ord ( $chr );
> else <
$chr = mb_convert_encoding ( $chr , ‘UTF-16BE’ , ‘UTF-8’ ); // $this->convertEncoding($chr, ‘UTF-16BE’, ‘UTF-8’);
$ord = hexdec ( bin2hex ( $chr ));
>
return sprintf ( ‘\\%X ‘ , $ord );
>;
$originalEncoding = mb_detect_encoding ( $string );
if ( $originalEncoding === false ) <
$originalEncoding = ‘UTF-8’ ;
>
;
$string = mb_convert_encoding ( $string , ‘UTF-8’ , $originalEncoding ); // $this->toUtf8($string);
// throw new Exception(‘mb_convert_encoding(\».$string.’\’,\’UTF-8\’,\».$originalEncoding.’\’);’);
if ( $string === » || ctype_digit ( $string )) <
return $string ;
>
$result = preg_replace_callback ( ‘/[^a-z0-9]/iSu’ , /*$this->*/ $cssMatcher , $string );
// var_dump($result);
return mb_convert_encoding ( $result , $originalEncoding , ‘UTF-8’ ); // $this->fromUtf8($result);
>

spamdunk at home dot com, your way is dangerous on PostgreSQL (and presumably MySQL). You’re quite correct that ANSI SQL specifies using ‘ to escape, but those databases also support \ for escaping (in violation of the standard, I think). Which means that if they pass in a string that includes a «\'», you expand it to «\»'» (an escaped quote followed by a non-escaped quote. WRONG! Attackers can execute arbitrary SQL to drop your tables, make themselves administrators, whatever they want.)

The best way to be safe and correct is to:

— don’t use magic quotes; this approach is bad. For starters, that’s making the assumption that you will be using your input in a database query, which is arbitrary. (Why not escape all «<«s with «&lt;»s instead? Cross-site scripting attacks are quite common as well.) It’s better to set up a way that does whatever escaping is correct for you when you use it, as below:

— when inserting into the database, use prepared statements with placeholders. For example, when using PEAR DB:

<?php
$stmt = $dbh -> prepare ( ‘update mb_users set password = ? where username = ?’ );
$dbh -> execute ( $stmt , array( ‘12345’ , ‘bob’ ));
?>

Notice that there are no quotes around the ?s. It handles that for you automatically. It’s guaranteed to be safe for your database. (Just ‘ on oracle, \ and ‘ on PostgreSQL, but you don’t even have to think about it.)

Plus, if the database supports prepared statements (the soon-to-be-released PostgreSQL 7.3, Oracle, etc), several executes on the same prepare can be faster, since it can reuse the same query plan. If it doesn’t (MySQL, etc), this way falls back to quoting code that’s specifically written for your database, avoiding the problem I mentioned above.

(Pardon my syntax if it’s off. I’m not really a PHP programmer; this is something I know from similar things in Java, Perl, PL/SQL, Python, Visual Basic, etc.)

PHP: Кавычки

С первыми двумя всё понятно, это точно строки, мы уже работали с подобными конструкциями и говорили, что строки — это наборы символов.

Любой одиночный символ в кавычках — это строка. Пустая строка '' — это тоже строка. То есть строкой мы считаем всё, что находится внутри кавычек, даже если это пробел, один символ или вообще отсутствие символов.

Ранее в уроках мы записывали строки в одинарных кавычках, но это не единственный способ. Можно использовать и двойные:

Представьте, что вы хотите напечатать строчку dragon's mother. Апостроф перед буквой s — это такой же символ, как одинарная кавычка. Попробуем:

Такая программа не будет работать. С точки зрения PHP строчка началась с одинарной кавычки, а потом закончилась после буквы n. Дальше были символы s mother без кавычек — значит, это не строка. А потом была одна открывающая строку кавычка, которая так и не закрылась: '); . Этот код синтаксически некорректен (это видно даже по тому, как подсвечен код).

Здесь нам помогут двойные кавычки. Такой вариант программы отработает корректно:

Теперь интерпретатор знает, что строка началась с двойной кавычки — значит и завершиться должна на двойной кавычке. А одинарная кавычка внутри стала частью строки.

Верно и обратное. Если внутри строки мы хотим использовать двойные кавычки, то саму строку надо делать в одинарных. Причём количество кавычек внутри самой строки не важно.

А что, если мы хотим создать такую строку:

В ней есть и одинарные, и двойные кавычки. Как быть в этой ситуации? Нужно каким-то образом указать интерпретатору считать каждую кавычку частью строки, а не началом или концом.

Для этого экранируют специальные символы. В нашем случае это символ, который является признаком конца и начала строки, — либо одинарная кавычка, либо двойная, в зависимости от ситуации. Для экранирования используется обратный слеш \ .

Посмотрите внимательно: нам нужно было добавить \ для двойных кавычек, но не для одинарной (апостроф), потому что сама строка создана с двойными кавычками. Если бы строка создавалась с одинарными кавычками, то символ экранирования нужен был бы перед апострофом, но не перед двойными кавычками.

А что, если нужно вывести сам обратный слеш? Точно так же, как и любой другой специальный символ, его надо экранировать самим собой.

Вопрос на самопроверку, что выведет этот код?

Задание

Напишите программу, которая выведет на экран:

Программа должна вывести на экран эту фразу в точности. Обратите внимание на кавычки в начале и в конце фразы:

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

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

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Это нормально ��, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.

Строки. Работа со строками в PHP

Строки — это последовательный набор символов.

Хотелось бы отметить, что в PHP нет встроенной поддержки Unicode .

В этом уроке мы познакомся с тем, какие способы объявления строк существуют в языке PHP.

Способы определения строк

В языке php предусмотрено 4 способа определения строк:

  • Строка обернута в двойные кавычки ("")
  • Строка обернута в одинарные кавычки
  • Синтактсис hereDoc
  • Синтаксис nowDoc

Одинарные кавычки

Одинарные кавычки — это простейший способ определить или объявить строку

У такого подхода, есть только один нюанс — это использование символа одинарной кавычки внутри строки. Для того чтобы использовать этот символ необходимо его экранировать.

Экранирование кавычек – это действие, которое используется для указания интерпритатору php о том, что определенный символ должем восприниматься им как текст, а не как символ. Для экранирования символов в php используется символ обратный слэш (\).

Двойные кавычки

У двойных кавычек — есть ряд отличий одинарных кавычек:

Во-первых, двойные кавычки поддерживают интерполяцию.

Интреполяция — механизм, который позволяет подставлять в строку значение переменной, а не ее название

Об интерполяции мы поговорим в следующих занятиях

Во-вторых у двойных кавычек гораздо больше список символов, которые стоит экранировать:

  • Двойная кавычка
  • Символ обратного слэша
  • знак $
  • управляющие последовательности, такие как \n (перенос строки), \t — табуляция и т.д.

Как и в строке, заключённой в одинарные кавычки, экранирование любого символа выведет также и сам символ экранирования.

Escape-последовательности и числовые нотации в PHP

Многие современные языки программирования поддерживают различные способы использования различных символов, таких как обычные английские латинские буквы, числа, символы, эмодзи и различные специальные символы, такие как символ новой строки или символ табуляции.

Большинство символов можно просто набрать с клавиатуры и использовать в коде PHP в их исходном виде. Например, $string = «php.watch» — это полностью допустимая строка в PHP, а $num = 42 — допустимое число. Также можно использовать многобайтные символы (для хранения которых требуется более одного байта), например, этот совершенно допустимый эмодзи: $emoji = «?» .

PHP, наряду со многими другими языками программирования, поддерживает определенное количество escape-последовательностей для использования различных символов, которые не могут быть набраны с обычной клавиатуры, не могут быть представлены в текстовой форме (например, невидимые символы или различные управляющие символы) или иным образом не считываются. Эти символы используют escape-последовательности, которые распознает PHP.

Что касается чисел, PHP поддерживает стандартные десятичные числа, но также может использовать и другие нотиции, такие как двоичное, восьмеричное, шестнадцатеричное и даже научное (scientific) представление. Они могут сделать код более читаемым и понятным в зависимости от контекста.

Двойные кавычки и Heredoc

В PHP строка с двойными кавычками ( «string» ) или Heredoc (смотрите ниже) поддерживает escape-последовательности и интерполяцию переменных.

PHP будет пытаться интерполировать переменные, если строковый литерал находится внутри строки с двойными кавычками или Heredoc.

Альтернативно (и желательно) интерполируемые переменные могут быть выделены фигурными скобками, так они будут выглядеть более удобочитаемыми:

Строки в одинарных кавычках ( ‘string’ ) и синтаксис Nowdoc не интерполируют переменные:

Только строки в двойных кавычках и Heredoc поддерживают escape-символы.

Экранирование символов

Поскольку PHP интерпретирует и интерполирует специальные символы внутри строковых литералов в двойных кавычках и heredoc, знак обратной косой черты ( \ ) используется как «escape-символ».

Например, использование \$name вместо $name не даст PHP интерполировать переменную $name .

Использование второго символа обратной косой черты предотвращает преобразование первого символа обратной косой черты в escape-символ.

PHP поддерживает несколько специальных escape-последовательностей для специальных символов. В приведенном выше примере \$ считается escape-последовательностью, потому что он отменяет интерполяцию PHP, заставляя PHP буквально использовать символ $ .

Символы табуляции: \t и \v

Возможно, самые простой из управляющих символов — это символ табуляции. Символ табуляции (по нажатию клавиши tab) можно использовать внутри строкового литерала, но использование \t вместо визуального пропуска делает его наглядным. Использование \t вместо буквального символа табуляции также позволяет избежать автоматической замены символов табуляции на пробелы в различных IDE.

\v — это вертикальная табуляция. На поддерживаемых терминалах символ вертикальной табуляции переходит к следующему символу в следующей строке:

Новые строки: \r и \n

\r («возврат каретки») и \n («перевод строки») являются символами новой строки.

Исторически так сложилось, что различные системы начали использовать либо \r , либо \n , и даже Windows использует \r\n . Например, Linux и MacOS по умолчанию используют символ «перевода строки» ( \n ) в качестве символа новой строки, тогда как Windows использует комбинацию \r\n (возврат каретки, за которым следует перевод строки). Старые системы MacOS использовали в качестве символа новой строки \r .

PHP имеет константу PHP_EOL , которая всегда ссылается на системный символ новой строки.

Escape-символ: \e

Escape-символы часто используется для отправки управляющих последовательностей ANSI в терминал. Например, \e , за которым следует [32m , указывает терминалу изменить цвет на зеленый, а [33m — на желтый.

Если приведенный выше фрагмент выполняется в терминале, который поддерживает управляющие последовательности ANSI, он интерпретирует его и изменяет текст:

Символ новой страницы: \f

Символ новой страницы — это управляющий символ ASCII для обозначения конца страницы. С его помощью принтеры могут вывести текущую страницу и начать с верхней части следующей. Когда \f передается на дисплейный терминал, он может результировать в очистке экрана, хотя это очень редкое поведение для большинства программ эмуляции терминала.

Восьмеричные escape-последовательности символов ASCII

PHP поддерживает экранирование восьмеричного числа в его соответствующий ASCII символ.

Например, ASCII символ P равен 80 в десятичной системе (смотрите диаграмму). 80 из десятичной системы счисления в переводе в восьмеричную — 120 .

Для символа P можно использовать восьмеричную escape-последовательность:

Любой базовый символ ASCII можно представить с помощью такой записи:

Любое значение в диапазоне от \0 до \377 будет интерпретироваться как восьмеричная escape-последовательность ASCII символа.

Обратите внимание, что числа для расширенных символов ASCII (от 128 до 255) несовместимы с UTF-8. PHP считает значение 128 (восьмеричное: 200 ; шестнадцатеричное: 80 ) недопустимым, поскольку оно не является допустимым значением UTF-8.

Хотя PHP принимает такие значения, они считаются недопустимыми символами в контексте UTF-8.

Шестнадцатеричные escape-последовательности символов ASCII

Подобно восьмеричным escape-последовательностям символов, PHP также допускает использование шестнадцатеричных чисел в escape-последовательности символов с префиксом \x .

Допускается только один байт, что подразумевает допустимый диапазон от x0 до xFF . Однако ограничение UTF-8 по-прежнему присутствует, и только значения до x80 будут считаться допустимыми символами.

Кроме того, шестнадцатеричные символы не чувствительны к регистру (т.е. AF равно af и aF ).

ASCII P — 80, что равно x50 :

Тот же «PHP.Watch» пример можно переписать с помощью шестнадцатеричных escape-последовательностей:

Escape-последовательности символов Unicode

PHP поддерживает использование любого Unicode символа с префиксом \u и шестнадцатеричным значением code point внутри фигурных скобок.

PHP выдаст ошибку парсера, если символ Unicode превышает значение 10FFFF :

10FFFF является верхним пределом, потому что спецификация UTF-8 объявляет диапазон от U+0000 до U+10FFFF .

В предыдущей версии этой статьи верхний предел неверно упоминался как FFFFF , что было исправлено на 10FFFF . Спасибо Саре Големон за то, что она указала на это.

Форму записи Unicode \u<> можно использовать качестве escape-последовательности для любого символа. Вот несколько примеров:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *