2010-03-12 30 views
18

J'ai essayé d'extraire les résultats de la requête MySQL en utilisant mysql_fetch_row() et mysql_result() et les valeurs numériques sont renvoyées en tant que chaînes.Obtenir les résultats de requête MySQL en tant que type de données natif?

Existe-t-il un moyen d'extraire les données en tant que type de données stockées dans la table?

L'application interrogera de nombreuses requêtes différentes, de sorte que je ne pourrai pas convertir les valeurs en tant que type de données prévu 1 par 1.

Répondre

14

Je ne pense pas que l'obtention de données dans leurs types de données natifs (ie toute autre chose que les chaînes) peut être fait en PHP 5.2 ...

En PHP 5.3, il devient possible, si je me souviens bien, lorsque vous utilisez le nouveau (nouveau comme dans PHP> = 5.3) pilote mysqlnd (MySQL Native Driver).

Après plus fouiller dans mes favoris, j'ai trouvé cet article sur mysqlnd: PDO_MYSQLND: The new features of PDO_MYSQL in PHP 5.3

Il dit ceci (citation):

Avantages de l'utilisation mysqlnd pour AOP

mysqlnd retourne natif types de données lorsque à l'aide des instructions préparées côté serveur, par exemple une colonne INT est renvoyé comme un entier variabl e pas comme une chaîne . Cela signifie moins de conversions de données internes .

Mais ceci est PHP 5.3 seulement (à condition que votre version de PHP 5.3 est compilé avec mysqlnd (et non l'ancien libmysql)), et semble être le cas que pour les commandes préparées :-(

qui n'a pas tout à fait de l'aide, dans votre situation, je suppose ...


Et voici un autre, toujours sur les nouvelles fonctionnalités de mysqlnd, qui parle de cela pour non seulement des déclarations préparées. PHP: New network traffic, CPU and memory savings with mysqlnd

Vous ne savez pas si cela a été fusionné dans le pilote mysqlnd officiel, cependant - le meilleur moyen serait d'essayer; mais il sera toujours PHP> = 5.3 seulement, de toute façon ...


Une autre solution serait d'avoir, sur le côté PHP, une sorte de système de cartographie (comme un ORM) à convertir les résultats en provenance de la DB PHP ... datatypes

et oui, cela est mauvais si vous voulez utiliser des opérateurs tels que === et !==, qui sont de type sensibles ...

+0

Merci Pascal MARTIN! Je googling depuis plusieurs heures et n'ai rien trouvé que je pourrais utiliser. Je suis relativement nouveau à PHP, mais il semble que je devrais aller avec PDO si je veux le support natif. Malheureusement, mon hôte est en cours d'exécution 5.2.something ... Aussi difficile, c'est que j'essaie de créer une entrée de fichier de rapport xml qui contient différentes informations de requête. Le script PHP lit le fichier xml demandé et envoie les requêtes à la base de données, donc je ne saurai jamais quelles données sont interrogées et comment elles doivent être retournées. temps pour être créatif je suppose :) –

+1

PDO ou pas PDO ne devrait rien changer, dans ce cas: ce qui compte est les pilotes utilisés sous * (libmysql vs mysqlnd) * - et je ne suis même pas sûr que mysqlnd dans PHP 5.3.2 renvoie des types natifs pour les requêtes standard ;;; dans votre cas, de toute façon, avec PHP 5.2, la seule solution que vous aurez sera une couche de mapping, qui tapera les conversions si nécessaire ... –

+0

Notez que vous devrez [désactiver l'émulation d'instruction préparée] (http://stackoverflow.com/a/15592818/441684) si vous utilisez PDO. –

3

J'ai mis ce la manière manuelle. Ce n'est pas trop mal, juste quelques lignes. Comme suggéré, appelez mysqli_fetch_fields() sur la ressource résultant de votre requête.Puis à partir d'un mappage des types de champs PHP vers les types de données MySQL (voir travail ici http://www.php.net/manual/en/mysqli-result.fetch-field-direct.php), vous pouvez convertir vos valeurs de la large gamme de types de bases de données renvoyés en chaînes par MySQLi, dans le type approprié en PHP.

Combien de ralentissement c'est que je ne suis pas sûr.

+0

c'est exactement ce dont j'avais besoin. Merci! – jbrahy

1

j'ai écrit une fonction pour circuvent ce (pour les AOP):

/** 
* Converts columns from strings to types according to 
* PDOStatement::columnMeta 
* 
* @param PDOStatement $st 
* @param array $assoc returned by PDOStatement::fetch with PDO::FETCH_ASSOC 
* @return copy of $assoc with matching type fields 
*/ 
function convertTypes(PDOStatement $statement, $assoc) 
{ 
    for ($i = 0; $columnMeta = $statement->getColumnMeta($i); $i++) 
    { 
     $type = $columnMeta['native_type']; 

     switch($type) 
     { 
      case 'DECIMAL': 
      case 'TINY': 
      case 'SHORT': 
      case 'LONG': 
      case 'LONGLONG': 
      case 'INT24': 
       $assoc[$columnMeta['name']] = (int) $assoc[$columnMeta['name']]; 
       break; 
      case 'DATETIME': 
      case 'DATE': 
      case 'TIMESTAMP': 
       $assoc[$columnMeta['name']] = strtotime($assoc[$columnMeta['name']]); 
       break; 
      // default: keep as string 
     } 
    } 

    return $assoc; 
} 

Bien sûr, la liste des types ne sont pas complètes et la conversion est simplifiée à l'extrême, mais peut être utile pour le démarrage.

3

essayer ceci si vous utilisez mysqli au lieu de PDO

$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1); 
+0

Cela a fait son travail pour moi. Je vous remercie! – Victor

-1

En plus de Pascal MARTIN réponse, si vous utilisez MySQLi devrait également fonctionner. Essayez ceci:

<?php 
$mysqli = new mysqli("example.com", "user", "password", "database"); 
if ($mysqli->connect_errno) { 
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error; 
} 

if (!$mysqli->query("DROP TABLE IF EXISTS test") || 
    !$mysqli->query("CREATE TABLE test(id INT, label CHAR(1))") || 
    !$mysqli->query("INSERT INTO test(id, label) VALUES (1, 'a')")) { 
    echo "Table creation failed: (" . $mysqli->errno . ") " . $mysqli->error; 
} 

$stmt = $mysqli->prepare("SELECT id, label FROM test WHERE id = 1"); 
$stmt->execute(); 
$res = $stmt->get_result(); 
$row = $res->fetch_assoc(); 

printf("id = %s (%s)\n", $row['id'], gettype($row['id'])); 
printf("label = %s (%s)\n", $row['label'], gettype($row['label'])); 
?> 

L'exemple ci-dessus sortie:

id = 1 (integer) 
label = a (string) 

Vous pouvez obtenir plus d'informations ici: https://dev.mysql.com/doc/apis-php/en/apis-php-mysqli.quickstart.prepared-statements.html

Hope this helps