PHP mysql_real_escape_string () -> stripslashes (), оставляющий множественные слэши

У меня возникли проблемы с экранированием / удалением строк с помощью PHP / MySQL – всегда кажется, что это лишние косые черты.


В качестве примера возьмем следующую строку:

<span style="text-decoration:underline;">underline</span> 

При добавлении строки в базу данных я mysql_real_escape_string() ее с помощью mysql_real_escape_string() и следующие данные сохраняются в базе данных ( EDIT : проверили это, запросив базу данных непосредственно с помощью приложения mysql):

 <span style=\\\"text-decoration:underline;\\\">underline</span> 

При чтении из базы данных я stripslashes() строку через stripslashes() и возвращается следующее:

 <span style=\"text-decoration:underline;\">underline</span> 

Поскольку кавычки все еще экранированы, он разбивает html, и текст не подчеркивается.


  1. Почему mysql_real_escape_string() добавляет три stripslashes() и stripslashes() удаляет две слэши? Я ожидаю, что они оба добавят / удалят одну косую черту.
  2. Как я могу предотвратить это?
  3. Правильно ли я подошел к этому?

Лучшее решение

В вашем файле php.ini есть вероятность, что для директивы magic_quotes_gpc установлено значение on. Это необходимо отключить по соображениям безопасности. Если у вас нет доступа к файлу php.ini (например, на общем хосте), вы всегда можете выполнить то же самое с помощью директивы .htaccess (при условии, что это сервер Apache).

В php.ini

 magic_quotes_gpc Off 

В файле .htaccess:

 php_flag magic_quotes_gpc Off 

Почему это происходит?

Причина, по которой это происходит, объясняется следующим курсом логики.

  1. Строка, которая требует экранирования, отправляется на сервер.
    • This is my string. It's awesome.
  2. Magic Quotes избегает апострофа, прежде чем он попадет в ваш код.
    • This is my string. It\'s awesome
  3. mysql_real_escape_string теперь есть два символа, которые можно избежать, обратная косая черта \\ а также апостроф \' .
    • This is my string. It\\\'s awesome
  4. Эта новая суперэкранированная строка хранится в базе данных.
  5. Когда строка извлекается из базы данных, она передается в stripslashes . Это удаляет два escapes, добавленных в шаге 3, но так как одна из обратных косых черт stripslashes думает, что это принадлежит.
    • This is my string. It\'s awesome

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

Альтернативное решение

Быстро и просто альтернативой было бы просто удалить косые черты, добавленные magic_quotes перед передачей строки в mysql_real_escape_string .

 $str = stripslashes($_POST['str']); $str = mysql_real_escape_string($str); 

При добавлении строки в базу данных я mysql_real_escape_string() ее с помощью mysql_real_escape_string() и следующие данные сохраняются в базе данных:

<span style=\\\"text-decoration:underline;\\\">underline</span>

Нет, это не так. Когда вы избегаете строк в запросе sql, он должен только переносить данные в запросе. База данных анализирует запрос и сохраняет данные в базе данных без каких-либо дополнительных косой черты. Таким образом, когда вы извлекаете данные из базы данных, вы не должны ничего игнорировать. Это распространенное заблуждение.

Если вы обнаружите, что на выходе есть лишние косые черты, вы, вероятно, включили магические кавычки. Выключите их .

Редактировать:

 mysql> create table foo (bar text) ; Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO foo (bar) VALUES ("<span style=\\\"text-decoration:underline;\\\">underline</span>"); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM foo; +-------------------------------------------------------------+ | bar | +-------------------------------------------------------------+ | <span style=\"text-decoration:underline;\">underline</span> | +-------------------------------------------------------------+ 1 row in set (0.00 sec) 

Как вы можете видеть, запрос имеет еще один уровень экранирования, чем данные отображаются в базе данных и, следовательно, как это получается при запросе на него. В вашем случае, что, вероятно, происходит, заключается в том, что вы включили магические кавычки, а затем вы избегаете строк, прежде чем встраивать их в запрос. Это приводит к двойному экранированию, подделке ваших данных. Правильное решение состоит в том, чтобы сохранить escape-строки, как вы, но отключите магические кавычки. И ничего не делайте с данными, поскольку они выходят из базы данных. Помните, что данные, которые уже в системе должны быть очищены в первую очередь.

Если get_magic_quotes_gpc() отключен в SERVER, так что только мы можем использовать

 $data= mysql_real_escape_string($_POST['data']); 

если get_magic_quotes_gpc() в SERVER, мы должны использовать

 $data= mysql_real_escape_string(stripslashes($_POST['data'])); 

в противном случае добавьте две обратные косые черты с вашими данными.

Еще одно решение – мы можем использовать stripslashes($data) при извлечении из datadase, если мы используем только mysql_real_escape_string($_POST['data']);