PHP ADOdb / PDO эквивалент Perl DBI quote_identifier? - PullRequest
2 голосов
/ 17 августа 2010

На моей нынешней работе стандартной практикой было использование mysql_query () и друзей напрямую. При построении больших запросов, поскольку наше стандартное развертывание на MySQL, имена таблиц просто вставляются и заключаются в обратные кавычки (частичный, поддельный пример):

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

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

Ответы [ 2 ]

1 голос
/ 17 августа 2010

К сожалению, в мире PHP нет ничего, что могло бы сравниться с потрясающим DBI. ЗОП - стоящая отправная точка.

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

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

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

0 голосов
/ 24 сентября 2014
/**
 * @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;
}
...