Безопасное сохранение массива в поле MySQL

Статус
В этой теме нельзя размещать новые ответы.
Спасибо, завтра на работе посмотрю. Всё-таки я для парсинга брал синтетический пример.
А на выходных не удается не то что разобраться, но редко и за компом посидеть.
Возможно, если и сейчас что-то работает, то позже перестанет.
Навскидку, если в исходном массиве будет что-то из этого списка:
PHP:
array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z');
то не должно оно нормально работать.
Просто потому, что невозможно предугадать, что на самом деле вырезал mysql_real_escape_string — мне кажется, это вырезалось необратимо. Может быть также, что mysql_real_escape_string ведет себя по-разному в разных версиях MySQL.
Впрочем, завтра проверю, возможно я и не прав.
Эта функция экранирует спецсимволы а не вырезает :conf:
 
решил данную проблему для себя через преобразование массива в формат JSON
 
Эта функция экранирует спецсимволы а не вырезает
Я вообще не знаю, что она делает. При этом её действия кажутся мне необратимыми, т.к. официально обратной функции не существует.
Предполагается, что экранированное mysql_real_escape_string преобразуется обратно и запишется в таком виде в БД, без слешей.
На деле же слеши зачастую остаются. Что приводит к невозможности распаковки бинарных файлов, сохраненных в .gz
У меня было такое несколько раз — и честно говоря, я не смог воспроизвести ошибку.
После ввода данных в профиль пользователя (там некоторые поля хранились через serialize) — распаковать данные назад на получилось.
Полез в БД — а там кое-где не вырезались слеши после mysql_real_escape_string
Разбираться дальше не стал, переписал функцию так, чтобы стало однозначно понятно как работает и надежно запаковывать и распаковывать данные.
решил данную проблему для себя через преобразование массива в формат JSON
Да какая разница — serialize или json? Речь о нестабильной работе mysql_real_escape_string и о том, что не хватает данных, что она на самом деле делает.
 
вполне стабильно работает, просто стоит повнимательней прочитать о экранировании спецсимволов, и как пхп, выводит строку с с экранированными символами
Я вообще не знаю, что она делает. При этом её действия кажутся мне необратимыми, т.к. официально обратной функции не существует.
зачем нужна обратная функция? задайтесь этим вопросом
На деле же слеши зачастую остаются. Что приводит к невозможности распаковки бинарных файлов, сохраненных в .gz
если они остаются то вы неправильно обрабатываете результат выборки из базы данных
Полез в БД — а там кое-где не вырезались слеши после mysql_real_escape_string
в зависимости от того как вы полезли в базу данных (например некоторые версии пхп-май-админ) слеши которыми экранированы спецсимволы попросту могут вам не отображаться, но это не означает что их там нет
mysql_real_escape_string и о том, что не хватает данных, что она на самом деле делает
по моему в мануале всё чётко и ясно описано - добавляет обратную косую черту к следующим символам: \x00, \n, \r, \, ', " и \x1a

посмотрел ваш пример и понял вашу ошибку, зачем применять mysql_real_escape_string вообще в данном случае?
вам нужно понять зачем вообще нужна эта функция а потом её использовать.

подумайте и поймите что ваш код это полнейшая ахинея, после функции serialize() применять mysql_real_escape_string() безсмысленно
 
Последнее редактирование модератором:
посмотрел ваш пример и понял вашу ошибку, зачем применять mysql_real_escape_string вообще в данном случае?
вам нужно понять зачем вообще нужна эта функция а потом её использовать.
Мне нужно понять КАК она работает, чтобы убедиться, что работает она правильно.
Если я не знаю, как работает код, я не могу быть уверен, что он работает правильно.
подумайте и поймите что ваш код это полнейшая ахинея, после функции serialize() применять mysql_real_escape_string() безсмысленно
Это Ваше мнение полнейшая ахинея, не в обиду. Посмотрите посты выше — я приводил тест.
Если после сериализации не экранируете данные, то Вы ССЗБ.
 
Скажи пожалуйста а зачем вообще экранировать твои данные? Что произойдет страшного если ты запишешь туда информацию как есть и получишь обратно как есть?
 
Скажи пожалуйста а зачем вообще экранировать твои данные? Что произойдет страшного если ты запишешь туда информацию как есть и получишь обратно как есть?
Кхм. Пользуйтесь, пожалуйста, запятыми.

Конкретно в моем проекте.
Данные вводятся пользователем и попадают в БД. Без экранирования — могут быть последствия от недоступности данных (расширенный профиль пользователя) до взлома сайта (если пользователь это умеет).
Вообще, в 2015 году об этом говорить даже не стоит. Ибо говорено уже 100500 раз. Удивительно, как такие вопросы вообще могут возникать.

Давайте не разводить флуд по типу — «а зачем безопасность?». Она нужна, и точка. Сообщения ради сообщений буду удалять.

Напомню, о чем шла речь. Данные при вставке в БД надо преобразовывать в безопасный для запроса вид (стандартным является экранирование mysql_real_escape_string).

Я обнаружил, что при вводе бинарных данных (сжатых в gz) mysql_real_escape_string не всегда экранирует символы правильно.
Поэтому предлагаю более безопасное и надежное решение, которое однозначно исключает применение «опасных» символов при вставке в БД.
Какое — читайте первый пост.
 
PHP:
    if (empty($arr) OR !is_array($arr)) return false;
    $data = base64_encode(gzcompress(serialize($arr)));
    return str_replace(array('+','/','='),array('-','_',''),$data);

Также в своих давних скриптах использовал похожие извращения. Но возникают вопросы по вашей реализации:
- чем вам не угодил пустой массив или не массив, возможно в вашем проекте это и критично, но универсальность кода теряется, ибо serialize всё проглотит
http://php.net/manual/ru/function.serialize.php написал(а):
string serialize ( mixed $value )
А задачи могут быть разные иногда и null надо сохранить, который вдруг словили вместо массива...

- что по вашему столь плохого в символах '+','/','=' для БД, ради чего стоит идти на замедление кода через str_replace и еще кучу кода в извлечении данных.
Опять таки в пределах вашего проекта такое может и не критично, но то что писал я обрабатывало больше 10кк полей и любой лишний код выливается в значительное время обработки.


В последнем проекте вполне успешно заменил все эти странные вещи на Для просмотра ссылки Войди или Зарегистрируйся и mysqli
 
Также в своих давних скриптах использовал похожие извращения. Но возникают вопросы по вашей реализации:
- чем вам не угодил пустой массив или не массив, возможно в вашем проекте это и критично, но универсальность кода теряется, ибо serialize всё проглотит
Обратная функция ждет массив или false. Ну не знаю, мне так удобнее.
- что по вашему столь плохого в символах '+','/','=' для БД, ради чего стоит идти на замедление кода через str_replace и еще кучу кода в извлечении данных.
Опять таки в пределах вашего проекта такое может и не критично, но то что писал я обрабатывало больше 10кк полей и любой лишний код выливается в значительное время обработки.
Это символы, которые могут быть восприняты как управляющие в запросе, от остальных мы избавились с помощью base64
А str_replace работает довольно быстро в PHP. Да, я параноик.
 
Иногда перед любым разработчиком встает вопрос — как сохранить массив в поле MySQL.
Когда перед разработчиком встает такой вопрос, стоит подумать над тем, что, что-то не так в архитектуре приложения.

//PS Буду рад, если найдется более красивое, краткое и быстрое решение.
Допустим пользователю необходимо ввести какую то информацию по реквизитам организации, и первое что приходит в голову программисту - ввести textarea поле где он может эти данные заполнить, чтобы потом их можно было бы достать. Но этим программист себе наживает неприятности на пятую точку, потому что в таком примере нужно либо предоставить возможность загрузки файла пользователю, либо создать столько полей, сколько требуется для идентификации данных со строгой типизацией (Даже PHP 7 к этому пришел в итоге :)) в БД.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху