2010-08-17 19 views
2

Dans mon travail actuel, la pratique standard consistait à utiliser mysql_query() et des amis directement. Lors de la construction de grandes requêtes, depuis notre déploiement standard est sur MySQL, les noms de tables juste s'insérés et entourés par des apostrophes inverses (par exemple partiel, faux):PHP ADOdb/PDO équivalent de Perl DBI quote_identifier?

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

Je suis en train de sortir de son MySQL-isme, et comme partie de cela, se déplaçant vers PDO et/ou ADOdb. Mais, je suis plus familier avec Perl que PHP, et j'ai été surpris de ne pas trouver facilement l'équivalent de DBI's quote_identifier, qui prend soit un nom de table unique, soit l'ensemble des informations d'identification (catalogue, schéma, table). Est-ce que je regarde quelque chose d'évident?

+0

a accepté la réponse à la question "Suis-je méconnais quelque chose d'évident?" - semble qu'il n'y a pas d'équivalent direct dans PDO ou ADOdb. – benizi

Répondre

1

Malheureusement, il n'y a rien en PHP qui se compare à l'impressionnant de DBI. PDO est un bon point de départ. Votre meilleur pari ne sera pas d'essayer de créer des guillemets d'identifiant spécifiques à la base de données, mais de dire à la base de données de suivre les normes. Turn on ANSI quotes, ce qui signifie que vous pouvez utiliser des guillemets doubles pour identifier les colonnes et les noms de tables. Ce format standard est accepté par la plupart des autres bases de données, y compris Postgres et SQLite. Certains (like MSSQL) ont également des paramètres similaires pour passer à des guillemets à partir d'une valeur par défaut non standard. En guise de mise en garde, cela signifie que vous devez toujours utiliser des guillemets simples lorsque vous citez une valeur littérale de chaîne au lieu de doubles. En outre, la plupart des identificateurs n'ont pas besoin d'être cotés, sauf s'il s'agit d'un mot-clé SQL ou s'ils sont réservés par la base de données.

Il existe lots d'autres étapes requises pour rendre SQL portable. Vous voudrez peut-être aller plus loin et utiliser un constructeur SQL ou un ORM.

+0

Bien conscient que la portabilité SQL est beaucoup plus impliquée que l'obtention d'une citation correcte. Était vraiment juste l'espoir de ne pas avoir à écrire quelque chose de type devis_identifier. Trop tard dans le jeu pour activer les citations ANSI compte tenu de la base de code actuelle. Je vais accepter votre réponse (que non, il n'y a pas d'équivalent évident) à moins que quelqu'un d'autre intervienne. Merci. – 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; 
} 

utilisation:

$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 (valeurs de citation intelligente, pas de connexion nécessaire!):

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