Как безопасно записывать массив от юзера в БД

Тема в разделе "Как сделать...", создана пользователем verfaa, 31 авг 2012.

  1. verfaa

    verfaa

    Регистр.:
    29 янв 2007
    Сообщения:
    375
    Симпатии:
    41
    В скрипт приходит массив чисел от юзера.
    С помощью ф-ции implode(",", $data["selects"]) из массива делается строка и пишется в БД.
    Каким образом в этом случае лучше всего поступить, чтобы не допустить попадания в базу возможного вредоносного кода и сделать скрипт безопаснее?
    Может в цикле обработать каждый элемент массива функцией intval ?
    Или есть решение получше?
     
  2. crazyzubr

    crazyzubr Создатель

    Регистр.:
    26 авг 2012
    Сообщения:
    23
    Симпатии:
    15
    Смотря какие цифры на какой позиции необходимы. Если не важно, то проще регуляркой проверить.

    PHP:
    $data_sel trim($data['selects'], ',');
    if (
    preg_match('/^(\d{1,10},?)+$/'$data_sel)){
    $selects implode(",",  $data_sel);
    }
    здесь предполагается, что максимум число может иметь 10 цифр (потому что придти может и бешенно длинная строка цифр) и должно быть положительным.

    в принципе, можно проверить также и на наличие пустых нулей впереди числа.

    PHP:
    //...
    if (preg_match('/^([1-9]\d{,9},?)+$/'$data_sel)){
    $selects implode(",",  $data_sel);
    }
    //..
     
  3. xymmep

    xymmep Постоялец

    Регистр.:
    7 дек 2007
    Сообщения:
    63
    Симпатии:
    22
    Если так, то не циклом.
    PHP:
    <?php
    function myint($n)
    {
        return(
    intval($n));
    }
     
    $a = array(12345"mnnthZsgb");
    $b array_map("myint"$a);
    print_r($b);
    ?>
    Например, проверить строку регуляркой, как предложено выше (я бы просто прогнал [\d,]), и, если что-то не так, уже через array_map.
     
    verfaa нравится это.
  4. verfaa

    verfaa

    Регистр.:
    29 янв 2007
    Сообщения:
    375
    Симпатии:
    41

    А зачем обрабатывать массив $data['selects'] функцией trim? И удалять запятые в начале и в конце?
    Ведь массив к этому моменту даже не обработан функцией implode, а значит выведет просто array
    Получается, мы просто обрабатываем слово array ф-ей trim. Или я не прав?
     
  5. crazyzubr

    crazyzubr Создатель

    Регистр.:
    26 авг 2012
    Сообщения:
    23
    Симпатии:
    15
    действительно,я почему то подумал, что уже приходит строка разделенных запятыми, а вместо implode следовало поставить explode в условии. ну это ерунда, тогда код становится еще проще:


    PHP:
    $data_sel implode(','$data['selects']);
    if (
    preg_match('/^([1-9]\d{,9},?)+$/'$data_sel)){
      
    //все остальные действия
    }
    //..
     
  6. verfaa

    verfaa

    Регистр.:
    29 янв 2007
    Сообщения:
    375
    Симпатии:
    41
    И ещё хотел уточнить, если мы передаём ф-ции preg_match вторым параметром массив, то она последовательно обрабатывает каждый элемент массива?
    Что-то гуглил описание к ней, нигде про это не сказано
     
  7. crazyzubr

    crazyzubr Создатель

    Регистр.:
    26 авг 2012
    Сообщения:
    23
    Симпатии:
    15
    сказано, например тут:

    http://www.php.su/functions/?preg-match

    mixed preg_match ( string pattern, string subject [, array &matches [, int flags [, int offset]]] )


    вторым параметром идет subject - типа string, вот если бы mixed или array тогда было бы над чем поразмышлять.
    поэтому функция только сравнивает строку по регулярке.
     
    verfaa нравится это.
  8. -=Xardas=-

    -=Xardas=-

    Регистр.:
    17 сен 2008
    Сообщения:
    250
    Симпатии:
    58
    Накой хрен тут регулярки вообще? Использовать их нужно к месту, а тут достаточно будет того что написал xymmep, только не понятно зачем городить такую пирамиду, достаточно сделать так:
    PHP:
    $stringToDB json_encode(array_map("intval"$data['selects']));
    p.s. размер числа в массиве не должен быть больше чем 2^(32-1)
     
  9. crazyzubr

    crazyzubr Создатель

    Регистр.:
    26 авг 2012
    Сообщения:
    23
    Симпатии:
    15
    все верно, этот вариант лучше, но если передавать вовсе не число, а какой-нибудь текст, то intval('текст') выдаст 0 и в строку запишется ноль, тогда как регулярка вообще подобные данные не пропустит, но это уже зависит от логики программы.

    в самой регулярке закралась ошибка, правильно будет: /^([1-9]\d{0,9},?)+$/
     
  10. xymmep

    xymmep Постоялец

    Регистр.:
    7 дек 2007
    Сообщения:
    63
    Симпатии:
    22
    Пример работы функции, и все. Когда ясна логика работы, то и дополнить код проще.
    Например, в моем примере легко заменить return(intval($n)); на любую проверку или правку данных. И это очевидно из кода.