2010-08-17 73 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; 
}