2010-08-17 4 views
2

В моей текущей работе стандартная практика заключалась в том, чтобы напрямую использовать mysql_query() и друзей. При построении больших запросов, так как наше стандартное развертывание на MySQL, имена таблиц просто вставляются и окруженная обратными кавычками (частичный, поддельный пример):PHP ADOdb/PDO эквивалент Perl DBI quote_identifier?

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

Я пытаюсь уйти от MySQL-изм, а также часть этого, двигаясь к PDO и/или ADOdb. Но я больше знаком с Perl, чем с PHP, и я был удивлен, что я не мог легко найти эквивалент DBI's quote_identifier, который принимает либо имя единственной таблицы, либо весь набор идентифицирующей информации (каталог, схема, таблица). Я не замечаю ничего очевидного?

+0

Принято ответ на вопрос "Могу ли я с видом что-то очевидное?" - похоже, нет прямого эквивалента в PDO или ADOdb. – benizi

ответ

1

К сожалению, на земле PHP нет ничего сравнимого с удивительным DBI. PDO является стоящей отправной точкой.

Ваш лучший выбор не будет пытаться создать кодовое обозначение, специфичное для конкретной базы данных, но сообщить базе данных о соответствии стандартам. Turn on ANSI quotes, что означает, что вы можете использовать двойные кавычки для идентификации столбцов и имен таблиц. Этот стандартный формат принимается большинством других баз данных, включая Postgres и SQLite. Некоторые (like MSSQL) также имеют аналогичные настройки для переключения на двойные кавычки из нестандартного значения по умолчанию.

В качестве предостережения это означает, что вы должны всегда должны использовать одинарные кавычки при цитировании строкового литерала вместо двухместных. Кроме того, большинству идентификаторов не нужно указывать, если они не являются ключевым словом SQL или зарезервированы в базе данных иначе.

Есть лоты других шагов, необходимых для создания портативного компьютера SQL. Возможно, вы захотите взглянуть на один шаг дальше и на самом деле использовать SQL-конструктор или ORM.

+0

Хорошо известно, что SQL-переносимость гораздо более активна, чем правильное использование таблицы. На самом деле просто надеялся не писать что-то вроде quote_identifier. Слишком поздно в игре включить ANSI, цитируя текущую кодовую базу. Я приму свой ответ (нет, нет очевидного эквивалента), если кто-то еще не вступит. Спасибо. – benizi

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` 

Bonus (смарт-кавычки значения, без подключения требуется!):

/** 
* 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; 
}