Обработка большого числа $_POST

Привет. Имеется БД с большим количеством колонок (а именно 36). Мне надо INSERT-тить туда данные которые приходят с $_POST запросом. Среди данных которые пришли с $_POST запросом есть обязательные (без которых я не смогу записать их в БД, т.к есть в них необходимость) и не обязательные (т.е дополнительная информация и если не внесу их в БД ничего страшного).

Вопрос собственно в слудующем, как осуществить наиболее эффективную проверку всего, что пришло мне $_POST. Сейчас я делаю следующее:

cоздал 2 массива (один с обязательными наименованиями колонок БД $base_key и другой со всеми $all_keys)

foreach -ом прогоняю весь пришедший $_POST и проверяю ключ на наличие в указанных выше массивах, а значение на не empty и все что проходит валидацию я добавляю к $into_sql

foreach($_POST as $key=>$value){
    if(!empty($value) && in_array(strtoupper($key), $all_keys)) {
        if(array_key_exists(strtoupper($key), $base_keys)) {$base_counter++; //считает количество обязательных колонок}
            $into_sql .= "`".$key."`='".$this->db->safeSQL($value)."', ";
        }
    }


if($base_counter >= sizeOf($base_keys)){

    $this->db->query("INSERT INTO `some_table` ".$into_sql." SERVER_DATE=NOW()");       
 }


В принципе все работает, как мне надо, единственное хотелось бы узнать у проффесионалов насколько эффективен данный код с точки зрения безопастности, скорости и надежности и есть ли более правильный вариант(или варианты)
  • Вопрос задан
  • 3435 просмотров
Решения вопроса 1
@egorinsk
Я бы убрал strtoupper. Он не нужен. Если программист на клиентсайде перепутал большие буквы с маленькими — пусть исправляет ошибку сам, а не скрипт за него это делает.

Собирать запрос к БД руками — неуклюже. Я бы свалил все в массив, и передал через плейсхолдеры вроде execute(«INSERT INTO ?table (?#) VALUES (?a)», $table, array_keys($data), array_values($data))

В остальном нормальный код, выполняющий свои функции. Хотя, конечно, кто-то предложит для этих целей сделать модели, репозитории, unit-of-work и что там еще придумал Мартин Фаулер для этих целей.

Если вам интересно, как это можно сделать сложнее, почитайте мануалы к любому фреймворку типа Yii или Zend или Symfony или Ruby on Rails или Джанго. Там вам расскажут про модели, валидаторы, хранилища, бекенды, слои абстракции и прочие умности.

И да, все эти ORM и фреймворки для PHP тяжелые, уродливые, и сам язык, из-за того что при каждом запросе надо инициализировать приложение заново, не позволяет их сделать нормальными, так что с точки зрения производительности лучше писать все руками.

Но я бы такой код писать не стал, так как мне надо, чтобы свойства модели и полей формы для ее модификации хранились в одном месте, а не были раскиданы по HTML-коду, яваскриптам и PHP-обработчикам. Забудешь же потом, где что менять, когда захочется например изменить лейбл у поля ввода. Также, ваш код не умеет ни делать валидацию переданных данных (передавай что хочешь — все запишет в БД), ни маппинг/сериализацию/джейсонизацию, а мне надо, чтобы все это было.
Ответ написан
Пригласить эксперта
Ответы на вопрос 6
dxArtem
@dxArtem
Появилась очень классная функция.

www.php.net/manual/en/function.filter-input-array.php

/* data actually came from POST
$_POST = array(
    'product_id'    => 'libgd<script>',
    'component'     => '10',
    'versions'      => '2.0.33',
    'testscalar'    => array('2', '23', '10', '12'),
    'testarray'     => '2',
);
*/

$args = array(
    'product_id'   => FILTER_SANITIZE_ENCODED,
    'component'    => array('filter'    => FILTER_VALIDATE_INT,
                            'flags'     => FILTER_REQUIRE_ARRAY, 
                            'options'   => array('min_range' => 1, 'max_range' => 10)
                           ),
    'versions'     => FILTER_SANITIZE_ENCODED,
    'doesnotexist' => FILTER_VALIDATE_INT,
    'testscalar'   => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_REQUIRE_SCALAR,
                           ),
    'testarray'    => array(
                            'filter' => FILTER_VALIDATE_INT,
                            'flags'  => FILTER_REQUIRE_ARRAY,
                           )

);

$myinputs = filter_input_array(INPUT_POST, $args);
Ответ написан
Комментировать
CrazySquirrel
@CrazySquirrel
Для таких вещей используються схемы данных.

Если ORM позволяет, схему можно получить от DB, и закешировать. Позволит избежать изменений в двух местах, при изменении структуры DB.
Ответ написан
@Severovostok Автор вопроса
Отсюда, понятно, что лучше на хабре вопросы не задавать, потому что количество одаренных не большое и те заняты делом, пишут статьи и отвечают на вопросы новичков, а кучка у которых есть кнопки и которые без надобности их используют (читай мудаки). Интересно однако, совсем другое, за что минус ставите, хоть напишите в комментарии, коль уж ответа написать не можете. И дело вовсе не в карме, а в людях или мудаках (каждый сам знает кто он), которые знаниями не обладают и поста не одного полезного не написали, а шутливыми комментариями набрали баллы.
Ответ написан
EugeneOZ
@EugeneOZ
«без которых я не смогу записать их в БД, т.к выставлено значение not null» — сможете записать, not null не обязывает заполнять. Будет просто 0 в цифровом или пустая строка в строковом поле.
Ответ написан
@Severovostok Автор вопроса
спасибо.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы