2010-12-09 34 views
4

J'utilise PHP wrapper personnalisé pour mysqli. La classe est conçue pour utiliser des instructions préparées si les paramètres bind sont passés à la fonction a fetchResultSet sinon, comme je le comprends, elle enregistre un appel à la base de données et utilise la fonction query (peut-être que je ne sais pas enregistrer un appel et le reste de il est possible de répondre à cette question en utilisant simplement des instructions préparées, même sans paramètre à lier).Fusion de données lors de l'utilisation de PHP MySQLi, Functions query et fetch_assoc

Une fois la requête exécutée, une fonction fetchResult renvoie l'un des deux objets ResultSetObjectResult ou ResultSetObjectStmt qui implémente une interface ResultSetObject. (L'objet ResultSetObjectStmt enveloppe un objet stmt pendant que le ResultSetObjectResult enveloppe un objet résultat.)

Les deux classes retournent un tableau associatif lorsqu'une ligne est demandée, en appelant fetch_assoc sur un résultat ou en appelant bind_result sur un objet stmt (fondamentalement). Ce que j'ai remarqué est que si une instruction préparée est exécutée alors les données retournées sont correctement castées en entiers, nombres réels et chaînes selon leurs types dans la base de données; mais quand un résultat est retourné et que fetch_assoc est appelé sur ce résultat, alors toutes les données sont castées en tant que chaînes. Je réalise que cela est mentionné dans la documentation de fetch_assoc. Je suis curieux de savoir s'il y a une autre fonction ou quelque chose que je peux faire pour que mysql jette correctement les résultats.

[EDIT] Je dois mentionner que ceci est seulement un problème car json_encode place les données entre guillemets en fonction de leurs types. J'aime savoir s'il est possible de convertir correctement les données renvoyées d'un résultat sans recourir à des devinettes en utilisant des fonctions comme is_numeric ou en effectuant un appel supplémentaire à la base de données pour le schéma de la table . En utilisant des instructions préparées exclusivement lors de l'extraction de données fonctionne, mais j'aimerais vraiment enregistrer cet appel de préparation supplémentaire à la base de données.

+0

pouvez-vous s'il vous plaît laissez-moi savoir ce que vous avez fait finalement? merci –

+0

Vous n'avez jamais trouvé de solution autre que d'utiliser des instructions préparées lorsque vous saisissez des données qui seront traduites en JSON, ou de lancer les résultats manuellement en utilisant PHP settype. – AWinter

Répondre

2

Je ne sais pas ce que votre emballage à l'aide, mais vous pourriez avoir une fonction comme ...

while ($row = $query->fetch_assoc()) { 
    $row = auto_cast($row); 
} 

function auto_cast($row) { 
    foreach ($row as $key => $value) { 
     if (ctype_digit($value)) { 
      $row[$key] = (int) $value; 
     } 
     elseif (is_numeric($value)) { 
      $row[$key] = (float) $value; 
     } 
     else { 
      $row[$key] = (string) $value; 
     } 
    } 
    return $row; 
} 
+0

L'encapsuleur est personnalisé. J'ai pensé à faire de la conversion de cette façon, mais je suis préoccupé par le fait que les valeurs qui devraient être des chaînes mais qui ne contiennent que des chiffres seraient transformées en entiers ou en flottants lorsque les chaînes sont le type de données approprié. Existe-t-il un moyen de diffuser en fonction du type de base de données sans faire une requête supplémentaire à la base de données pour le schéma de la table? – AWinter

+0

Il peut y avoir mais pas un que je suis au courant de ... – fire

+0

Merci pour l'info. Je ne savais pas à propos de ctype_digit ... 5 ans de PHP et les choses me plaisent toujours. – AWinter

1

Je vais essayer d'aider ici. Lorsque l'instruction usign prepare, le PHP sait quel est le type de la colonne et en fonction de cela stocke les données dans différents types: chaîne, entier, booléen, etc. Lorsque vous utilisez fetch_assoc, il ne connaît pas cette information. Vous pouvez créer une fonction qui récupère les champs/colonnes de données MySQL en utilisant mysqli_fetch_fields et utilise leur type. Sur cette base, vous pourriez les classer. J'espère que cela aidera.

Fior informations sur les différents types de colonnes voir ici http://www.php.net/manual/en/mysqli.constants.php

MYSQLI_TYPE_LONG - Le champ est INT un ainsi de suite.

+0

Ceci est une option de défi, mais j'essaie d'éviter de faire un appel supplémentaire à la base de données. – AWinter

+0

Est-ce que cela serait moins cher que d'exécuter chaque requête en tant qu'instruction préparée avec des paramètres à lier ou non? – AWinter

+0

Vous feriez mieux de rester avec la déclaration préparée. Ma suggestion est juste au cas où vous voulez utiliser fetch_array. –