这篇 文章已经是07年的了,不过,我一直没有关注过drupal的db类,所以对于这方面我也根本 就没有在意过。8过,我在我的siterpc中,我也是采用了sprintf的写法,不是为了安全,而是为了格式化。因为在siterpc里我们几乎不接受外部变量,所有的变量都是由我们自己传入,所以对于安全方便忽略了很多。但还是用sprintf来格式化SQL语句了。
因此看到这篇drupal的db_query安全过滤,突然发现,可以让我的代码少写很多了。(参数可变时请使用vsprintf)
以下是原文 :
Drupal通过C风格的字符串输出格式实现了对sql语句的安全过滤。
使用方法:
- db_query("SELECT n.nid FROM {node} n WHERE n.type = '%s'", $type);//正确做法
- //这不等于以下语句,使用sprintf并不能避免mysql注入。
- db_query(sprintf("SELECT n.nid FROM {node} n WHERE n.type = '%s'", $type)); //不正确
- /**
- * Indicates the place holders that should be replaced in _db_query_callback().
- */
- define('DB_QUERY_REGEXP', '/(%d|%s|%%|%f|%b)/');
- /**
- * Runs a basic query in the active database.
- *
- * User-supplied arguments to the query should be passed in as separate
- * parameters so that they can be properly escaped to avoid SQL injection
- * attacks.
- *
- * @param $query
- * A string containing an SQL query.
- * @param ...
- * A variable number of arguments which are substituted into the query
- * using printf() syntax. Instead of a variable number of query arguments,
- * you may also pass a single array containing the query arguments.
- * Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
- * in '') and %%.
- *
- * NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
- * and TRUE values to decimal 1.
- *
- * @return
- * A database query result resource, or FALSE if the query was not
- * executed correctly.
- */
- function db_query($query) {
- $args = func_get_args();
- array_shift($args);
- $query = db_prefix_tables($query);
- if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
- $args = $args[0];
- }
- _db_query_callback($args, TRUE);
- $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
- return _db_query($query);
- }
- /**
- * Helper function for db_query().
- */
- function _db_query_callback($match, $init = FALSE) {
- static $args = NULL;
- if ($init) {
- $args = $match;
- return;
- }
- switch ($match[1]) {
- case '%d': // We must use type casting to int to convert FALSE/NULL/(TRUE?)
- return (int) array_shift($args); // We don't need db_escape_string as numbers are db-safe
- case '%s':
- return db_escape_string(array_shift($args));
- case '%%':
- return '%';
- case '%f':
- return (float) array_shift($args);
- case '%b': // binary data
- return db_encode_blob(array_shift($args));
- }
- }
原文来自于:http://www.luochunhui.com/id/315