Во-первых, вопросы, я с вашим кодом:
eval
очень, очень редко требуется, и крайне опасно, следует использовать с осторожностью. Я развиваюсь в PHP более 10 лет, и никогда действительно столкнулся с ситуацией, которая необходима eval
. Это не исключение. Eval не требуется
- Вы дезинфицируете весь массив
$_POST
. Это здорово, но для этого есть специальные функции: filter_input_array
, array_filter
и многие, многое другое ... не говоря уже о готовых проектах с открытым исходным кодом и фреймворках, которые уже содержат надежный компонент проверки запроса.
- Всегда проверяйте возвращаемые значения функций, которые вы, кажется, делать с
strstr
, но устанут функции, которые возвращают различные типы (как strstr
: она возвращает false
, если игла не найдена, но возвращает 0
, если игла находится в начале строки haystack). Ваш оператор if
может не работать должным образом.
- Вы принимаете значения
sanitize($value)
, значения не будут содержать ни одной кавычки. Зачем? Потому что если они это сделают, вы в конечном итоге с синтаксической ошибки в вашей evaled строке
Как бы то ни было, вы могли бы легко написать код, используя переменные переменныеи добавить простую проверку чтобы не наступить на существующих переменных в области видимости:
$sanitized = array_filter($_POST, 'sanitize');//call sanitize on all values
foreach ($sanitized as $key => $value)
{
if (!isset($$key) && strstr($key, 'removeFile') === false)
$$key = $value;
}
Но на самом деле, $_POST
ценности принадлежат вместе, они являются частью запроса, и должны оставаться сгруппированы ... либо в массиве или в объекте своего рода , Не назначайте каждое значение своей переменной, потому что довольно скоро вы потеряете информацию о том, какие переменные установлены, а какие нет. Использование отключенное переменной создает эту переменную, назначая значение null
, так что у вас есть теперь делает для очень к ошибкам кода:
//request 1: POST => id=123&foo=bar
foreach ($sanitized as $k => $v)
$$k = $v;
$query = 'SELECT x, y, z FROM tbl WHERE id = ?';//using posted ID as value
$stmt = $db->prepare($query);
$stmt->execute(array($id));
Все хорошо, потому что $id
был установлен, но никогда не доверяют сеть, не думайте, что только потому, что $_POST
установлен, все ключи будут установлены, и их значения будут правильными:
//request 2: POST => foo=bar&page=2
foreach ($sanitized as $k => $v)
$$k = $v;
$query = 'SELECT x, y, z FROM tbl WHERE id = ?';//using posted ID as value
$stmt = $db->prepare($query);
$stmt->execute(array($id));//id is null
Теперь у нас есть проблемы. Это всего лишь один пример того, как ваш код может вызвать проблемы. Представьте себе сценарий растет немного, и смотреть на это:
//request 3: POST => id=123&foo=bar&page=2
foreach ($sanitized as $k => $v)
$$k = $v;
//$id is 123, $foo is bar and $page = 2
$query = 'SELECT x, y, z FROM tbl WHERE id = ? LIMIT 10';//using posted ID as value
//a lot more code containing this statement:
$page = someFunc();
$log->write('someFunc returned log: '.$page);
//more code
$offset = 10*($page-1);//<-- page is not what we expected it to be
$query .= sprintf(' OFFSET %d', $offset);
$stmt = $db->prepare($query);
$stmt->execute(array($id));
Сейчас это может показаться надуманным, и идиотская, но поверьте мне: все эти вещи случиться больше, чем я хочу знать.Добавление некоторого кода, который случайно перезаписывает существующую переменную, которая используется дальше, происходит все время. Особенно в процедурном коде. Не просто слепо распаковать массив. Держите эти одну переменные и использовать ключи, чтобы избежать:
- седым волосам
- внезапно, драматично облысением
- потери здравомыслия
- кровоточащей язвы
- В рабочей среде: катастрофические потери данных
- Внезапная потеря работы
- ... так как такой код заставляет единорогов плакать, а bronies wi ll hunt you down
'eval (" \ $ ". $ Key." = '". Sanitize ($ value)."'; ");' Это ** прямо в ответах на первый вопрос, который вы связали **. – sjagr
Запомнить; Eval === Evil –
Это не самый лучший способ, просто используйте массив: '$$ key = sanitize ($ value);' будет лучше. – AbraCadaver