J'utilise PDO et MySQL, pour une raison quelconque lors de l'obtention de valeurs de la base de données de type int, le PDOStatement renvoie une représentation sous forme de chaîne du nombre et non une valeur de type numérique. Comment puis-je empêcher que cela se produise?
J'ai remarqué qu'il y a un attribut de la classe PDO: PDO::ATTR_STRINGIFY_FETCHES
qui est censé s'en occuper mais, en essayant de le modifier, il génère une erreur indiquant que l'attribut n'est pas valide pour le pilote MySQL.
Est-il normal d'obtenir des chaînes au lieu de chiffres lors de la consultation d'une base de données?
Je ne pense pas qu'avoir des "nombres" puisse se faire 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) mysqlnd (MySQL Native Driver) pilote.
Eh bien, après avoir fouillé mes signets, 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 de mysqlnd pour PDO
mysqlnd renvoie des types de données natifs lors de l'utilisation d'instructions préparées côté serveur, par exemple une colonne INT est renvoyée sous forme de variable entière et non sous forme de chaîne. Cela signifie moins de conversions de données en interne.
Mais c'est PHP 5.3 uniquement (à condition que votre version de PHP 5.3 soit compilée avec mysqlnd ( et pas l'ancien libmysql) ), et ne semble être le cas que pour les déclarations préparées :
Désolé...
Une solution serait d'avoir, du côté de PHP, un système de cartographie (comme un ORM - voir --- (Doctrine ; juste comme exemple d'ORM: je ne sais pas si il fait ce que vous demandez) pour convertir les résultats provenant de la base de données en PHP types de données ...
Et oui, c'est mauvais si vous voulez utiliser des opérateurs comme ===
et !==
, qui sont sensibles au type ...
Pour répondre d'abord à votre dernière question, "oui", malheureusement, il est normal de recevoir des nombres sous forme de chaînes. Comme le dit le manuel cité par Pascal, mysqlnd (PHP 5.3) renverra les types de données natifs des instructions préparées, à condition de désactiver l'émulation des instructions préparées à partir de PDO.
new PDO($dsn, $user, $pass, array(
PDO::ATTR_EMULATE_PREPARES => false
))
PDO :: ATTR_STRINGIFY_FETCHES n'est pas lié à MySQL.
Si vous regardez le bon côté des choses, il est bon d'utiliser quand même des instructions préparées, alors ...;)
réponse de Pascal est correct. J'ai eu du mal à le faire fonctionner. Voici ce que tu dois faire.
Tout d'abord, assurez-vous que mysqlnd est installé et activé. Regarder php --info
. Dans la section pdo_mysql, cela devrait ressembler à:
pdo_mysql
PDO Driver for MySQL => enabled
Client API version => mysqlnd 5.0.8-dev - 20102224 - $Revision: 321
Si au lieu de voir mysqlnd
dans la version de l'API client, vous voyez une ligne comme ...
Client API version => 5.5.29
... alors vous n'avez pas installé et activé mysqlnd. Prenez soin de cela en premier.
Deuxièmement, PDO utilise des instructions préparées émulées par défaut pour toutes les connexions MySQL . Ridicule, mais ça y est. Et vous n'obtiendrez des types de données natifs que si vous utilisez de véritables instructions préparées (appelées "instructions préparées côté serveur" dans le billet de blog lié, qui est maintenant ici ). Vous devez donc définir PDO :: ATTR_EMULATE_PREPARES sur false, comme ceci:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
Enfin, assurez-vous que vous n'avez pas défini PDO :: ATTR_STRINGIFY_FETCHES sur true.
$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
Vous pouvez avoir mysqlnd
installé, mais cela ne signifie pas qu'il est prêt à être utilisé par l'extension régulière PDO
(pdo_mysql)
, c'est plus souvent le cas sur l'hébergement mutualisé, donc assurez-vous d'activer le nd_pdo_mysql
extension, ainsi que pour désactiver les autres extensions pdo_mysql
car cela pourrait créer un conflit.
@capture d'écran
J'ai trouvé ceci (en double) question , j'ai décidé de poster mes pensées ici, j'espère que ça va;)