За последние 24 часа нас посетили 22943 программиста и 1238 роботов. Сейчас ищут 762 программиста ...

Экранирование в MySQL

Тема в разделе "PHP для новичков", создана пользователем sumsum, 29 июн 2014.

  1. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Подскажите пожалуйста как правильно экранировать данные, которые нужно добавлять в БД? Я вот делаю вот так:
    Код (Text):
    1. mysql_real_escape_string
    но в этом случае когда в тексте есть скобка то в БД заносится /' короче фигня какая то ... В общем вопрос - как экранировать данные НО не портить текст?
     
  2. VLK

    VLK Старожил

    С нами с:
    15 дек 2013
    Сообщения:
    3.010
    Симпатии:
    58
    а при выводе выводит тоже с '/''?
    если вдруг ДА, найди функцию убирающую из текста экранирующие символы.
    такую функцию можно найти в этой теме - viewtopic.php?f=13&t=48916
     
  3. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Покажите код. В базу ничего лишнего заносится при экранировании этой функцией не должно.
     
  4. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Ну как же, если сделать
    $opis = mysql_real_escape_string($opis);
    $SQL = "INSERT INTO data SET `opis` = '$opis'";
    mysql_query ($SQL,$db) or die(mysql_error());

    И когда в $opis было
    то стало
     
  5. kamael

    kamael Новичок

    С нами с:
    29 июн 2014
    Сообщения:
    9
    Симпатии:
    0
    Посмотри примечания
    http://php.ru/manual/function.mysql-real-escape-string.html
    А также -- ещё интересная тема - А если этой функцией будет обрабатываться полный текст например статьи и закидываться в базу?
    Дофига лишнего будет походу.
    (это хорошо что от слешей можно почистить текст, а если они нужны... много хлама и обработчиков для примитивного действия)
     
  6. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Это где вы, интересно, хостинг с магическими кавычками включенными откопали? Или на локале у вас включены? У вас двойное экранирование получается - один раз PHP из-за включенных магических кавычек, второй раз - mysql_real_escape_string. Лучше выключить магические кавычки :) Если на настройки вы не влияете, то воспользуйтесь функциями http://php.ru/manual/function.get-magic-quotes-gpc.html и http://php.ru/manual/function.stripslashes.html
     
  7. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Не могу понять так функцию stripslashes($str) нужно использовать потом при извлечении данных из БД? Но тогда получается в БД все равно будут заноситься данные со слешами или я что то не понимаю? Можно ли сделать что бы именно в БД хранились данные нормальные без слешей?
     
  8. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    не надо решать несуществующих проблемм.

    эскейпинг нужен только на этапе передачи строки в базу. база не хранит экранирующие слеши и от них не придется избавляться после чтения.

    проверить самостоятельно нетрудно, правда?
     
  9. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    На старых версиях пхп нужно отключать magic_quotes_gpc или если это невозможно, примерить stripslashes перед экранированием, иначе многие символы экранируются дважды. Подробно http://phpfaq.ru/slashes
    А еще некоторые динозавры включают magic_quotes_runtime что вообще непростительно.
     
  10. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    [vs], это да. но лучше не перед экранированием, а вообще перед всем. потому что magic quotes может внезапно подосрать и в других местах, где никто не ждал лишних символов. это такая же попаболь старых версий, как register_globals.

    пример лекарства: в движке fluxbb любой скрипт сначала подключает common.php, а там делается проверка на нежданчик magic_quotes_gpc и при наличии сразу избавляется от слешей. таким образом остальной код остается чистым.
    https://github.com/fluxbb/fluxbb/blob/master/include/common.php#L76
     
  11. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    У меня теория расходится с практикой :( вот в вашей методичке написано:
    Но я то вижу, что в базе со слешами хранится. Я так понял это из-за настроек хостинга а именно magic_quotes, есть функция которая может проверять их включение или нет get_magic_quotes_gpc() но можно ли принудительно их выключить? А еще в том примере с MySQL они не используются только для вывода данных:
    Там ведь четко написано If using MySQL то используем функцию mysql_real_escape_string без всяких проверок на магические скобки ...

    Что то я запутался
     
  12. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    плохо!

    если тебе доступен для редактирования php.ini — найди там magic quotes и выключи. сервер перезагрузи.
    если недоступен — лекарство есть в моей ссылке выше. сделай аналогичную чистку, помести в файл, который подключается в самом начале работы.

    Добавлено спустя 1 минуту 18 секунд:
    ну если ты способен на иронию, значит справишся ))) главное — не паникуй.
     
  13. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Сделал функцию:
    Код (Text):
    1. if (get_magic_quotes_gpc())
    2. {
    3.     function stripslashes_array($array)
    4.     {
    5.         return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
    6.     }
    7.  
    8.     $_GET = stripslashes_array($_GET);
    9.     $_POST = stripslashes_array($_POST);
    10.     $_COOKIE = stripslashes_array($_COOKIE);
    11.     $_REQUEST = stripslashes_array($_REQUEST);
    12.     if (is_array($_FILES))
    13.     {
    14.         // Don't strip valid slashes from tmp_name path on Windows
    15.         foreach ($_FILES AS $key => $value)
    16.             $_FILES[$key]['tmp_name'] = str_replace('\\', '\\\\', $value['tmp_name']);
    17.         $_FILES = stripslashes_array($_FILES);
    18.     }
    19. }
    И все работает отлично, НО работает только когда человек вводит двойные кавычки ", а если одинарные ' то MySQL ругается
    Код (Text):
    1. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Рога и копыта' AND `tov_dem_' at line 6
    Как теперь еще и одинарные кавычки победить? :)
     
  14. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    видимо у тебя нет эскейпинга ))) или прямые кавычки с косыми попутал. короче сам виноват.
    перед тем как выполнить запрос, сделай как-то так:
    echo $sql;
    $result = mysql_query($sql);

    полный текст запроса скопируй и покажи нам
     
  15. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Код (Text):
    1. INSERT INTO data SET `opis` = 'ЗАО \\\"Торговый Дом\\\" Рога и\\\"\\\" тел. 8(495)123-45-67 e-mail: info@info.ru г. Москва ул. Колодезная д5К' ...
    Получается все равно слэши в БД заносятся
     
  16. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Да, заносятся, но только при двойном экранировании! Т.к. при повторном экранировании экранируются не только кавычки, но и следи, добавленные при первом экранировании, т.к. слеш - тоже спецсимвол!
     
  17. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Ну так как избавится от этой проблемы? Я уже сделал как мне рекомендовали выше и не помогает
    Код (Text):
    1. if (get_magic_quotes_gpc())
    2. {
    3.    function stripslashes_array($array)
    4.    {
    5.       return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
    6.    }
    7.  
    8.    $_GET = stripslashes_array($_GET);
    9.    $_POST = stripslashes_array($_POST);
    10.    $_COOKIE = stripslashes_array($_COOKIE);
    11.    $_REQUEST = stripslashes_array($_REQUEST);
    12.    if (is_array($_FILES))
    13.    {
    14.       // Don't strip valid slashes from tmp_name path on Windows
    15.       foreach ($_FILES AS $key => $value)
    16.          $_FILES[$key]['tmp_name'] = str_replace('\\', '\\\\', $value['tmp_name']);
    17.       $_FILES = stripslashes_array($_FILES);
    18.    }
    19. }
     
  18. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Если ты используешь код из своего прошлого сообщения, то там ненужный addslashes
     
  19. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
  20. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    А не, это просто echo. Короче кидай весь код или ищи где повторяется экранирование
     
  21. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Сделал вот так:
    Код (Text):
    1. $e_opis = stripslashes($e_opis);
    2. $e_opis = mysql_real_escape_string($e_opis);
    и вроде все заработало - я правильно так сделал?
     
  22. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    нет

    Добавлено спустя 30 секунд:
    просят тебя по хорошему — покажи весь код
     
  23. sumsum

    sumsum Новичок

    С нами с:
    13 май 2014
    Сообщения:
    96
    Симпатии:
    0
    Почему нет если все заработало? :)

    Код я уже показывал:

    Беру данные из БД если пользователь не ввел
    Код (Text):
    1. if($e_opis==""){$e_opis=GetUserContact($ses_user);}
    дальше
    Код (Text):
    1. $e_opis = stripslashes($e_opis);
    2. $e_opis = mysql_real_escape_string($e_opis);
    подготавливаем к БД
    Код (Text):
    1. $SQL = "INSERT INTO data
    2.                 SET
    3.                     `opis` = '{$e_opis}',;
    4.                 print $SQL."<br><hr><br>";
    5.                 mysql_query ($SQL,$db) or die(mysql_error());
    Вот теперь все работает как надо - и одинарные и двоичные кавычки экранирует и что самое главное в БД все заносится без слешей ... зачем что то менять если все работает - все довольны :)))
     
  24. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    А как работает GetUserContact?
     
  25. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    потому что необходимость stripslashes в этом месте говорит о том, что у тебя в целом бардак! это говностайл, непереносимый код.

    где у тебя подключается код, который magic quotes нейтрализует, он вообще инклудится? проверь себя с помощью die('подключено!');
    и почему в этом коде не упоминаются вот эти строки:
    Код (PHP):
    1. // Turn off magic_quotes_runtime