UPDATE 1:
I get the following error:
Fatal error: Cannot pass parameter 2 by reference in /var/www/page1.php on line 42 Call Stack: 0.0008 341836 1. {main}() /var/www/page1.php:0
When using:
if( $_SERVER['REQUEST_METHOD'] == 'POST') {
$fields = array(
'col1' => 'cb1',
'col2' => 'cb2',
'col3' => 'cb3',
'col4' => 'cb4',
);
$parts = array();
foreach($fields as $dbfield => $field)
$parts[] = '`' . $dbfield . '` = :' . $dbfield;
$dbh = new PDO('mysql:host=localhost;dbname=database', 'user', 'pass');
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $dbh->prepare('UPDATE `table1` SET ' . join(', ', $parts) . ' WHERE `id `= :id');
// temp simulation value
$id = 1;
$sth->bindParam(':id', $id, PDO::PARAM_INT, 4);
foreach($fields as $dbfield => $field)
$sth->bindParam(':' . $dbfield, isset($_POST[$field]) ? 1 : 0, PDO::PARAM_INT, 1);
$sth->execute();
}
ORIGINAL QUESTION:
Will the following code prevent SQL injections?
<?php
if( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
// all the way upto 50
$fields = array('col1'=>'cb1', 'col2'=>'cb2', 'col3'=>'cb3', 'col4'=>'cb4');
$update = '';
foreach($fields as $dbfield => $field) {
if ($update) $update.= ',';
$update.= ' '.$dbfield.'=';
$update .= isset($_POST[$field]) ? 1 : 0;
}
$DBH = new PDO( "mysql:host=localhost;dbname=database", "user", "pass" );
$DBH -> setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$STH = $DBH -> prepare( "update table1 set " . $update . " where id = :id" );
// temp simulation value
$id = 1;
$STH -> bindParam( ':id', $id, PDO::PARAM_INT, 4 );
$STH -> execute();
}
?>
<html>
<head>
<title></title>
</head>
<body>
<form method="post">
<input type="checkbox" name="cb1" />
<input type="checkbox" name="cb2" />
<input type="checkbox" name="cb3" />
<input type="checkbox" name="cb4" />
<!-- all the way to 50 -->
<input type="submit" value="submit" />
</form>
</body>
</html>
Well, in your particular case, SQL injection cannot go through this code because you’re only constructing your update out of pre-known column names, 1s and 0s. The overall way you’re constructing that update would be a very dangerous practice to repeat in other contexts, though. The thing is, you’re using PDO, but then forcing it to send a raw string with no escaping of your data, which defeats everything PDO can do to try to protect you.
In order to actually use what PDO does for you against SQL injection, you need to write the query with
?or named placeholders for data and usebindParamto supply the values.An example of dynamic construction using binding of named parameters might look like: