PHP + PDO + MySQL: Comment puis-je retourner des colonnes entières et numériques de MySQL sous forme d'entiers et de nombres en PHP?

j'ai vu cette question répétée plusieurs fois sur Stack Overflow mais aucune n'explore suffisamment le problème (ou du moins d'une manière qui m'est utile)

Le problème est qu'une requête DB doit renvoyer des types de données entiers en PHP pour les colonnes entières. Au lieu de cela, la requête renvoie chaque colonne en tant que type de chaîne.

J'ai veillé à ce que "PDO::ATTR_STRINGIFY_FETCHES" if false juste pour s'assurer que les résultats ne sont pas convertis en chaîne.

Réponses que j'ai vu:

  • ça ne peut pas être fait
    • non, il fonctionne sur Mac OS X installé PHP / MySQL
  • Type cast toutes vos valeurs dans votre code
    • Non, Je ne ferai pas ça
  • Ne vous inquiétez pas, PHP est vaguement tapé
    • mes données sont sorties en tant que JSON et sont consommées par de nombreux autres services, certains nécessitent les données dans le format correct

D'après mes recherches, je comprends qu'il s'agit d'un pilote problème de mise en œuvre.

De nombreuses sources affirment que le pilote natif MySQL ne prend pas en charge le retour des types numériques. Cela ne semble pas vrai car cela fonctionne sur Mac OS X. À moins qu'ils ne signifient dire que "le pilote natif MySQL sur Linux ne supporte pas la fonctionnalité".

Cela implique qu'il ya quelque chose de spécial sur le pilote/l'environnement que j'ai installé sur Mac OS X. j'ai essayé d'identifier les différences afin d'appliquer un correctif, mais je suis limité par mes connaissances comment vérifier ces choses.

Les différences:

  • PHP sur OS X a été compilé et installé via Home Brew
  • PHP sur Ubuntu a été installé via "apt-get install php5-dev"
  • PHP sous OS X se connecte à un serveur MySQL fonctionnant également sous OS X
    • Version du serveur: 5.1.71-log distribution Source
  • PHP sur Ubuntu se connecte à une base de données Rackspace Cloud
    • Version du serveur: 5.1.66-0 + squeeze1 (Debian)

Environnement Ubuntu

  • Version: 10.04.1
  • PHP 5.4.21-1+debphp.org~lucid+1 (cli) (construit: Octobre 21 2013 08:14:37)
  • Php-i

    Pdo_mysql

    Pilote PDO pour MySQL = > activé Version de l'API Client = > 5.1.72

Environnement Mac OS X

  • 10.7.5
  • PHP 5.4.16 (cli) (construit: août 22 2013 09:05:58)
  • Php-i

    Pdo_mysql

    Pilote PDO pour MySQL = > activé Version de l'API Client => mysqlnd 5.0.10 - 20111026 - $Id: e707c415db32080b3752b232487a435ee0372157 $

Drapeaux AOP utilisés

PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
PDO::ATTR_EMULATE_PREPARES => false,

Toute aide et expertise serait appréciée :) je vais certainement poster ici si je trouve la réponse.

67
demandé sur stephenfrank 2013-11-19 22:33:34

1 réponses

La solution est de vous assurer que vous utilisez le pilote mysqlnd pour php.

Comment savez-vous que vous n'utilisez pas mysqlnd?

Lors de l'affichage de php -i, il n'y aura pas de mention de "mysqlnd". La section pdo_mysql aura quelque chose comme ceci:

pdo_mysql

PDO Driver for MySQL => enabled Client API version => 5.1.72

Comment l'installez-vous?

La plupart des guides d'installation pour L/a/M/P suggèrent apt-get install php5-mysql mais le pilote natif de MySQL est installé par un paquet différent: php5-mysqlnd. J'ai trouvé que c'était disponible avec le ppa:ondrej/php5-oldstable.

Pour passer au nouveau pilote (sur Ubuntu):

  • Supprimer l'ancien pilote:
    apt-get remove php5-mysql
  • Installer le nouveau pilote:
    apt-get install php5-mysqlnd
  • Redémarrer apache2:
    service apache2 restart

Comment puis-je vérifier que le pilote est utilisé?

Maintenant php -i mentionnera explicitement" mysqlnd " dans la section pdo_mysql:

pdo_mysql

PDO Driver for MySQL => enabled
Client API version => mysqlnd 5.0.10 - 20111026 - $Id:      e707c415db32080b3752b232487a435ee0372157 $

Paramètres PDO

Assurez - vous que PDO::ATTR_EMULATE_PREPARES est false (vérifiez vos valeurs par défaut ou réglez le):
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

Assurez - vous que PDO::ATTR_STRINGIFY_FETCHES est false (vérifiez vos valeurs par défaut ou définissez-le):
$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);

Valeurs renvoyées

  • les types à virgule flottante (FLOAT, DOUBLE) sont renvoyés sous forme de flotteurs PHP.
  • les types entiers (INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT†) sont renvoyés sous forme D'entiers PHP.
  • les types à points fixes (décimaux, numériques) sont renvoyés sous forme de chaînes.

† BIGINTs avec une valeur supérieure à un int signé 64 bits (9223372036854775807) retournera sous forme de chaîne (ou 32 bits sur un système 32 bits)

    object(stdClass)[915]
      public 'integer_col' => int 1
      public 'double_col' => float 1.55
      public 'float_col' => float 1.5
      public 'decimal_col' => string '1.20' (length=4)
      public 'bigint_col' => string '18446744073709551615' (length=20)
100
répondu stephenfrank 2016-06-07 06:25:00