littleguga
@littleguga
Не стыдно не знать, а стыдно не интересоваться.

Почему так работает, а так нет?

Здравствуйте, можете объяснить, почему первый код работает, а второй нет?

$sql = "UPDATE `$dbname` SET `bText`=:bText WHERE `type`=:type AND `bId`=:bId";
$stm = $pdo->prepare($sql);
$stm->bindParam(":bText", $_POST['bText']);
$stm->bindParam(":type", $_POST['type']);
$stm->bindParam(":bId", $_POST['bId']);
$stm->execute();


$sql = "UPDATE `$dbname` SET `bText`=:bText WHERE `type`=:type AND `bId`=:bId";
$stm = $pdo->prepare($sql);
foreach($_POST as $key => $val){
	if(!in_array($key,$not)){
		$stm->bindParam(":$key", $val);
		echo ":$key - $val"; //это выводит правильно :bText - и значение $_POST['bText']
	}
}
$stm->execute();


Заранее благодарен за ответ!
  • Вопрос задан
  • 2688 просмотров
Решения вопроса 2
Denormalization
@Denormalization
С PHP.NET:

Связывает PHP переменную с именованным или неименованным параметром подготавливаемого SQL запроса. В отличие от PDOStatement::bindValue(), переменная привязывается по ссылке, и ее значение будет вычисляться во время вызова PDOStatement::execute().


Во втором случае в момент, когда происходит связывание переменная уже не существует. Попробуйте использовать bindValue.
Ответ написан
Комментировать
FanatPHP
@FanatPHP
Чебуратор тега РНР
Потому что во втором случае ты занимаешься ерундой.
Причем дважды
Раз уж ты используешь именованные плейсхолдеры, то зачем их привязывать по одному? Ну ведь они специально сделаны для того, чтобы просто передать ассоциативный массив в execute()!
Тем более, что у тебя совершенно правильная идея отфильтровать ненужное из массива $_POST. Ну так вот сначала отфильтруй, а потом тупо передавай на исполнение, без всяких циклов. Только способ фильтрации у тебя неправильный. Надо не лишнее выкидывать, а нужное контролировать.

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

$in = ['bText','type','bId'];
$data = array_intersect_key($_POST, array_flip($in));
$sql = "UPDATE `$dbname` SET `bText`=:bText WHERE `type`=:type AND `bId`=:bId";
$stm = $pdo->prepare($sql);
$stm->execute($data);


А так-то да, Денормализатор правильно написал. Я же тебе давал ссылку, в которой написано, что bindValue() всегда следует предпочесть bindParam(). Там же написано, что ни ту ни другую использовать не нужно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
код верен, если переменные и массивы корректны, какая ошибка?
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы