If each column type is a PDO::PARAM_STR
, then it is fairly simple to bind your parameters to unamed paramter markers using PDOStatement::execute. However, if the column types vary, then you need to specify the column type for each column when you bind to it with PDOStatement::bindParam.
Accepting table and column names from what appears to be user input, is not a good idea. The query will fail if the table or column names are incorrect, but you need to be very careful to ensure that the table and column names are safe to use. The following example checks the table and column names against a whitelist, prior to executing any SQL:
function insert($postValues, $table) {
$dbh = $this->connect();
// Create a simple whitelist of table and column names.
$whitelist = array('my_table' => array('col1', 'col2', 'col3'));
// Check if the table name exists in the whitelist.
if(!array_key_exists($table, $whitelist)) {
exit("$table is not a valid table name.\n");
}
// Count the number of columns that are found in the whitelist.
$cols = count(
array_intersect(
$whitelist[$table],
array_keys($postValues)));
if($cols !== count($postValues)) {
exit("One or more invalid column names have been supplied.\n");
}
// Create a comma separated list of column names.
$columns = implode(', ', array_keys($postValues));
// Create a comma separated list of unnamed placeholders.
$params = implode(', ', array_fill(0, count($postValues), '?'));
// Create a SQL statement.
$sql = "INSERT INTO $table ($columns) VALUES ($params)";
// Prepare the SQL statement.
$stmt = $dbh->prepare($sql);
// Bind the values to the statement, and execute it.
return $stmt->execute(array_values($postValues));
}
echo insert(
array(
'col1' => 'value1',
'col2' => 'value2',
'col3' => 'value3'),
'my_table');
// 1
echo insert(
array(
'col1' => 'value1',
'col2' => 'value2',
'col3' => 'value3'),
'unsafe_table');
// unsafe_table is not a valid table name.
echo insert(
array(
'col1' => 'value1',
'col2' => 'value2',
'unsafe_col' => 'value3'),
'my_table');
// One or more invalid column names have been supplied.