2010-08-17 53 views
2

在我目前的工作中,标准做法是直接使用mysql_query()和朋友。当构建大型查询,因为我们的标准部署是在MySQL,表名只得到插入和反引号(部分,假的例子)包围:PHP ADOdb/PDO相当于Perl DBI quote_identifier?

$sql .= "from `$tablename`"; 

我试图从MySQL主义的逃脱,并作为其中一部分,向PDO和/或ADOdb移动。但是,我比Perl更熟悉Perl,而且我很惊讶,我无法轻松找到相当于DBI's quote_identifier的文件,它只有一个表名,或者是一组标识信息(目录,模式,表)。我忽略了一些明显的东西?

+0

接受答案的问题: “我俯瞰明显的东西?” - 似乎在PDO或ADOdb中没有直接的等价物。 – benizi 2010-08-18 16:34:58

回答

1

不幸的是,与DBI的真棒相比,PHP土地上没有任何东西。 PDO是一个有价值的出发点。

最好的办法不是试图创建DB特定的标识符引用,而是告诉数据库遵循标准。 Turn on ANSI quotes,这意味着您可以使用双引号来标识列和表名。这种标准指定的格式被大多数其他数据库所接受,包括Postgres和SQLite。某些(like MSSQL)也具有类似的设置,可以从非标准默认切换到双引号。

作为一个告诫,这意味着你会总是必须使用单引号引用字符串文字值而不是双打。此外,大多数标识符不必被引用,除非它们是SQL关键字或由数据库保留。

还有很多需要其他步骤使SQL便携式。您可能想要更进一步,并实际使用SQL构建器或ORM。

+0

意识到SQL可移植性远比引用表引用更为重要。真的只是希望不必写一些类似quote_identifier的东西。考虑到当前的代码库,在游戏中打开ANSI引用的时间太晚了。除非有其他人介入,否则我会接受你的回答(不,没有明显的等同物)。谢谢。 – benizi 2010-08-17 18:41:05

0
/** 
* @param string|string[]$identifiers 
* @param string $tableName 
* @param string $dbName 
* @return string[]|string 
*/ 
static public function quoteIdentifiers($identifiers, $tableName='', $dbName=''){ 
    if(is_array($identifiers)){ 
     $result = array(); 
     foreach($identifiers as $identifier){ 
      $result[] = self::quoteIdentifiers($identifier, $tableName, $dbName); 
     } 
    }else{ 
     $result = '`'.str_replace('`','``',$identifiers).'`'; // escape backtick with backtick 
     if($tableName){ 
      $result = '`'.$tableName.'`.'.$result; 
     } 
     if($dbName){ 
      $result = '`'.$dbName.'`.'.$result; 
     } 
    } 
    return $result; 
} 

用法:

$columns = quoteIdentifiers(array('my col1', 'my col2'), 'table'); 
$sql = 'SELECT '.join(',', $columns); 
$sql=.' FROM '.quoteIdentifiers('table'); 
=> SELECT `table`.`my col1`,`table`.`my col2` FROM `table` 

奖金(智能报价值,无需要连接!):

/** 
* quote a value or values 
* @param string|string[]|int|int[] $value 
* @return string[]|string 
*/ 
static public function quoteValues($value) { 
    if(is_array($value)){ 
     $result = array_map(__METHOD__, $value); 
    }elseif($value===true){ 
     $result = 'TRUE'; 
    }elseif($value===false){ 
     $result = 'FALSE'; 
    }elseif($value===null){ 
     $result = 'NULL'; 
    }elseif(is_int($value) OR is_float($value) OR (is_string($value) AND $value===strval($value*1))){ 
     $result = strval($value); // no quote needed 
    }else{ 
     $result = "'".str_replace(
         array('\\',  "\0", "\n", "\r", "'",  '"', "\x1a"), 
         array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), 
         strval($value)). "'"; 
    } 
    return $result; 
}