如果在你的SQL中,有多个只有在运行时才能确定的变量,这并不妨碍让你使用占位符。你将需要使用占位符比如'%s' 或者 %d,通过编程来创建你的SQL,接着你需要传递一组值来填充这些占位符。如果你自己直接调用db_escape_string(),那么你就做错了。下面的例子展示了占位符的使用,这里假定我们想取出,匹配特定节点类型的已发布节点的ID和标题:
// $node_types is an array containing one or more node type names
// such as page, story, blog, etc.
$node_types = array('page', 'story', 'blog');
// Generate an appropriate number of placeholders of the appropriate type.
$placeholders = db_placeholders($node_types, 'text');
// $placeholders is now a string that looks like '%s', '%s', '%s'
$sql = "SELECT n.nid, n.title from {node} n WHERE n.type IN ($placeholders)
AND status = 1";
// Let db_query() fill in the placeholders with values.
$result = db_query(db_rewrite_sql($sql), $node_types);
运行完db_rewrite_sql()以后,db_query()的调用看起来的样子如下所示:
db_query("SELECT DISTINCT(n.nid), n.title from {node} n WHERE n.type IN
('%s','%s','%s') AND status = 1", array('page', 'story', 'blog'));
现在当db_query()执行时,将对节点类型的名称进行清理。如果你想知道具体的缘由,可参看includes/database.inc中的db_query_callback()。
下面是另一个例子。有时你处在这样的一种情况,你想在一个查询的WHERE语句中添加一些AND限制条件来限制查询语句。此时,你也需要小心点使用占位符。在下面的例子中我们假定$uid 和 $type的值都是有效的(例如,3和page)。
$sql = "SELECT n.nid, n.title FROM {node} n WHERE status = 1";
$where = array();
$where_values = array();
$where[] = "AND n.uid = %d";
$where_values[] = $uid;
$where[] = "AND n.type = '%s'";
$where_values[] = $type;
$sql = $sql . ' ' . implode(' ', $where) ;
// $sql is now SELECT n.nid, n.title
// FROM {node} n
// WHERE status = 1 AND n.uid = %d AND n.type = '%s'
// The values will now be securely inserted into the placeholders.
$result = db_query(db_rewrite_sql($sql), $where_values));
老葛的Drupal培训班 Think in Drupal