Насколько важно проверять каждый индекс массива в PHP? - PullRequest
1 голос
/ 15 февраля 2011

Я работаю над довольно большим проектом, в котором есть много мест, где существует код, подобный следующему:

function foo($a, $b, $c, $d, $e, $f) {
    $clean = array();
    $mysql = array();

    $clean['a'] = htmlentities($a);
    $clean['b'] = htmlentities($b);
    $clean['c'] = htmlentities($c);
    $clean['d'] = htmlentities($d);
    //...

    $mysql['a'] = mysql_real_escape_string($clean['a']);
    $mysql['b'] = mysql_real_escape_string($clean['b']);
    $mysql['c'] = mysql_real_escape_string($clean['c']);
    $mysql['d'] = mysql_real_escape_string($clean['d']);
    //...

    //construct and execute an SQL query using the data in $mysql
    $query = "INSERT INTO a_table
              SET a='{$mysql['a']}',
                  b='{$mysql['b']}',
                  c='{$mysql['c']}',
                  d='{$mysql['d']}'";
}

Очевидно, что в PHP выдается много предупреждений для неопределенных индексов.

Действительно ли необходимо переписать код следующим образом?

function foo($a, $b, $c, $d, $e, $f) {
    $clean = array();
    $mysql = array();

    $clean['a'] = htmlentities($a);
    $clean['b'] = htmlentities($b);
    $clean['c'] = htmlentities($c);
    $clean['d'] = htmlentities($d);
    //...

    $mysql['a'] = (isset($clean['a'])) ? mysql_real_escape_string($clean['a']) : mysql_real_escape_string($a);
    $mysql['b'] = (isset($clean['b'])) ? mysql_real_escape_string($clean['b']) : mysql_real_escape_string($b);
    $mysql['c'] = (isset($clean['c'])) ? mysql_real_escape_string($clean['c']) : mysql_real_escape_string($c);
    $mysql['d'] = (isset($clean['d'])) ? mysql_real_escape_string($clean['d']) : mysql_real_escape_string($d);
    //...

    //construct and execute an SQL query using the data in $mysql
    if (isset($mysql['a']) and isset($mysql['b']) and isset($mysql['c']) and isset($mysql['d'])) {
        $query = "INSERT INTO a_table
                  SET a='{$mysql['a']}',
                      b='{$mysql['b']}',
                      c='{$mysql['c']}',
                      d='{$mysql['d']}'";
    }

}

Ответы [ 5 ]

1 голос
/ 15 февраля 2011

Вы можете значительно упростить свою функцию, если используете:

function foo($a, $b, $c, $d, $e, $f) {

    $args = func_get_args();   // or build an array() manually

    $args = array_map("htmlentities", $args);
    $args = array_map("mysql_real_escape_string", $args);

    list($a, $b, $c, $d, $e, $f) = $args;

Проверка isset () в показанной позиции кажется совершенно бесполезной. Переменные уже определены.

1 голос
/ 15 февраля 2011

Да, если индекс массива или переменная не существует, php выдаст предупреждение / уведомление.

Правильный способ - проверить каждую переменную перед использованием их с функцией isset().

Рекомендуется проверять их перед использованием.

1 голос
/ 15 февраля 2011

Нужно ли вообще иметь такую ​​жестко закодированную функцию?

Я использую это:

function insert_array($table, $data) {  
    $cols = '(';
    $values = '(';
    foreach ($data as $key=>$value) { 
        $value = mysql_real_escape_string($value);
        $cols .= "$key,";  
        $values .= "'$value',";  
    }
    $cols = rtrim($cols, ',').')';
    $values = rtrim($values, ',').')';  
    $sql = "INSERT INTO $table $cols VALUES $values";
    mysql_query($sql) or die(mysql_error());
}

Затем для вставки данных независимо от их имени и столбцов используйте:

$data = array('id' => 1, 'name' => 'Bob', 'url' => 'foo.com');
insert_array('users', $data);
0 голосов
/ 15 февраля 2011

Если ваш проект очень большой, то неопределенные индексы могут стать ночной кошмаром, особенно если они содержат данные, сгенерированные пользовательским вводом, и ОСОБЕННО в отсутствие хороших отчетов об ошибках с трассировкой стека. Это связано с тем, что, поскольку данные передаются между запросами, нет гарантии, что они были установлены в исходной точке входа, и поэтому вы в конечном итоге выполняете много избыточных проверок на наличие нулевых или пустых значений.

Возможно, вы захотите проверить, не может ли то, что вы пытаетесь достичь, достичь этой цели лучше, превратив эту функцию в объект. Значения, которые вы представляете с помощью $ a $ b и $ c, могут быть легко преобразованы в свойства объекта, а один метод save () может сохранить состояние в базе данных.

Кроме этого, вы можете выполнять проверку намного быстрее и более согласованно, используя цикл foreach. Просто перебирайте данные по их ключам и выполняйте реальный переход и htmlentities в теле цикла.

http://php.net/manual/en/control-structures.foreach.php

Я также предлагаю HTMLPurifier для вашей фильтрации XSS, так как очень часто htmlentites недостаточно, особенно для общедоступных форм, которые допускают размещение пользовательского контента в веб-приложении.

http://htmlpurifier.org/

0 голосов
/ 15 февраля 2011

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

  1. В вашем примере вы можете переместить часть mysql_real_escape_string внутрь, если вы проверяете переменные, то вы уже знаете, что они существуют.

  2. Нет необходимости использовать здесь массивы, вы можете хранить их в одной переменной.

  3. XSS-Protection (htmltentities (), обратите внимание, что этого недостаточно) следует сделать перед удалением данных, а не перед сохранением, как в вашем примере. Только одна причина в том, что вы будете иметь дело с вещами, которые кодируются / экранируются несколько раз. Вредоносный HTML / JS не может навредить вашей базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...