PHP PDO + Подготовить заявление - PullRequest
5 голосов
/ 30 декабря 2011
$sql='SELECT phrase,english FROM static_site_language WHERE page=?;';
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['languagepage']));

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

$sql='SELECT phrase,? FROM static_site_language WHERE page=?;';
$pds=$database->pdo->prepare($sql); $pds->execute(array($_POST['language'],$_POST['languagepage']));

Я знаю, что $ _POST ['language'] (из печати) содержит только слово «english».Можно ли поместить подготовленную переменную в эту часть выбора?

thx

Ответы [ 2 ]

7 голосов
/ 30 декабря 2011

Параметры запроса могут заменять только постоянное значение, а не имя столбца.

Все столбцы и таблицы должны быть названы в то время, когда вы готовите запрос, вы не можете откладывать выбор столбцов до следующего шага выполнения.

Если вы хотите, чтобы пользовательский ввод определял имя столбца, используйте Карта белого списка , чтобы ограничить пользовательский ввод допустимыми вариантами. Ключи массива карты являются допустимыми пользовательскими вводами. Значения массива карты - это строки, которые вы хотите использовать в запросе SQL, в данном случае имена столбцов.

$lang_col_map = array(
  "DEFAULT" => "english",
  "en"      => "english",
  "es"      => "spanish"
);
$lang_col = $lang_col_map[ $_POST["language"] ] ?: $lang_col_map[ "DEFAULT" ];

$sql='SELECT phrase,$lang_col FROM static_site_language WHERE page=?;';
$pds=$database->pdo->prepare($sql); 
$pds->execute(array($_POST['languagepage']));

Таким образом, вы можете быть уверены, что только значения в $ lang_col_map могут стать частью запроса SQL, и если пользователь пытается отправить что-нибудь хитрое в запросе http, он игнорируется, потому что он не соответствует ни одному из ключей этого карта. Таким образом, запрос защищен от внедрения SQL.

См. Мою презентацию Мифы и ошибки SQL-инъекций для получения дополнительной информации.

2 голосов
/ 30 декабря 2011

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

Во втором утверждении первый «?»является заполнителем для имени столбца, а не значения.

Вместо этого вы должны использовать динамический оператор SQL.Для этого вы должны предотвратить внедрение SQL.

$language_authorized = array('english', 'french', 'spanish');
$language = $_POST['language'];
if (in_array($language_authorized, $language)) {
  $sql='SELECT phrase,'.$language.' FROM static_site_language WHERE page=?;';
  $pds = $database->pdo->prepare($sql);
  $pds->execute(array($_POST['languagepage']));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...