Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
442 views
in Technique[技术] by (71.8m points)

sql - Are Dynamic Prepared Statements Bad? (with php + mysqli)

I like the flexibility of Dynamic SQL and I like the security + improved performance of Prepared Statements. So what I really want is Dynamic Prepared Statements, which is troublesome to make because bind_param and bind_result accept "fixed" number of arguments. So I made use of an eval() statement to get around this problem. But I get the feeling this is a bad idea. Here's example code of what I mean

// array of WHERE conditions
$param = array('customer_id'=>1, 'qty'=>'2');
$stmt = $mysqli->stmt_init();

$types = ''; $bindParam = array(); $where = ''; $count = 0;

// build the dynamic sql and param bind conditions
foreach($param as $key=>$val)
{
    $types .= 'i';
    $bindParam[] = '$p'.$count.'=$param["'.$key.'"]'; 
    $where .= "$key = ? AND ";
    $count++;
}

// prepare the query -- SELECT * FROM t1 WHERE customer_id = ? AND qty = ?
$sql = "SELECT * FROM t1 WHERE ".substr($where, 0, strlen($where)-4);
$stmt->prepare($sql);

// assemble the bind_param command
$command = '$stmt->bind_param($types, '.implode(', ', $bindParam).');';

// evaluate the command -- $stmt->bind_param($types,$p0=$param["customer_id"],$p1=$param["qty"]);
eval($command);

Is that last eval() statement a bad idea? I tried to avoid code injection by encapsulating values behind the variable name $param.

Does anyone have an opinion or other suggestions? Are there issues I need to be aware of?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think it is dangerous to use eval() here.

Try this:

  • iterate the params array to build the SQL string with question marks "SELECT * FROM t1 WHERE p1 = ? AND p2 = ?"
  • call prepare() on that
  • use call_user_func_array() to make the call to bind_param(), passing in the dynamic params array.

The code:

call_user_func_array(array($stmt, 'bind_param'), array($types)+$param);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...