2009-07-28 15 views
53

Estoy usando PDO y MySQL, por alguna razón al obtener valores de la base de datos que son de tipo int, PDOStatement está devolviendo una cadena de representación del número y no un valor de tipo numérico. ¿Cómo evito que esto suceda?¿Cómo obtener tipos numéricos de MySQL usando PDO?

Me di cuenta de que hay un atributo de la clase PDO: PDO::ATTR_STRINGIFY_FETCHES que se supone que se ocupa de esto pero, al intentar modificarlo, arroja un error diciendo que el atributo no es válido para el controlador MySQL.

¿Es normal obtener cadenas en lugar de números al consultar una base de datos?

Respuesta

37

No creo tener "números" se pueden hacer en PHP 5.2 :-(

En PHP 5.3, se hace posible, si no recuerdo mal, cuando se utiliza la nueva (nueva como en PHP> = 5.3) MySQL nd(driver nativo de MySQL) controlador

Bueno, después de rebuscar entre mis marcadores he encontrado este artículo sobre mysqlnd:. PDO_MYSQLND: The new features of PDO_MYSQL in PHP 5.3

Se dice que esta (cita):

Ventajas del uso de mysqlnd de DOP

mysqlnd vuelve tipos de datos nativos cuando utilizando comandos preparados en el servidor, por ejemplo una columna INT es devuelto como una variable entera no como una cadena . Eso significa menos conversiones de datos internamente.

Pero esto es solamente PHP 5.3 (siempre que su versión de PHP 5.3 se compila con mysqlnd (y no tenía la edad libmysql)), y parece que sólo ser el caso de las declaraciones preparadas :-(

Lo sentimos ...

Una solución sería tener, en el lado de PHP, un sistema de mapeo (como un ORM - ver Doctrine; solo como un ejemplo de ORM: No sé si lo hace lo que está preguntando) para convertir resultados provenientes de los tipos de datos DB a PHP ...

Y sí, esto es malo si desea utilizar operadores como === y !==, que son de tipo sensible ...

+7

En Ubuntu tratan 'sudo apt-get install php5-mysqlnd ' – Alex

+0

Yo también tuve que hacer lo que @Alex dijo aquí para tener php use mysqlnd bajo el capó. +1 por su comentario. – Zugwalt

+0

Avance rápido hasta 2016, para tener los tipos de datos correctos devueltos de MySQL, para PHP 7 en CentOS/RHEL: 'yum install php70w-mysqlnd' –

55

para responder a su última pregunta, "sí", por desgracia, es normal recibir números instrumentos de cuerda. Como dice el manual citado por Pascal, mysqlnd (PHP 5.3) devolverá los tipos de datos nativos de las declaraciones preparadas, siempre que apague la emulación de declaración preparada de PDO.

new PDO($dsn, $user, $pass, array(
    PDO::ATTR_EMULATE_PREPARES => false 
)) 

PDO :: ATTR_STRINGIFY_FETCHES no está relacionado con MySQL.

Si nos fijamos en el lado positivo, es una buena práctica usar comandos preparados de todos modos, así que ...;)

+2

esta es la respuesta ganadora ^.^ – naomik

+0

De acuerdo. Esta es la única respuesta que funcionó para mí. Gracias. –

+0

claramente la respuesta ganadora – eightyfive

24

Pascal's answer es correcta.Tuve algunos problemas haciendo que todo funcione. Aquí está lo que tú necesitas hacer.

Primero, asegúrese de tener mysqlnd instalado y activado. Mira php --info. En la sección pdo_mysql, que debe ser similar:

pdo_mysql 

PDO Driver for MySQL => enabled 
Client API version => mysqlnd 5.0.8-dev - 20102224 - $Revision: 321 

Si en lugar de ver mysqlnd en la versión de la API de cliente, se ve una línea como ...

Client API version => 5.5.29 

... entonces usted don' tengo mysqlnd instalado y funcionando. Cuida eso primero.

En segundo lugar, PDO utiliza instrucciones preparadas emuladas by default for all MySQL conexiones. Ridículo, pero ahí está. Y obtendrá tipos de datos nativos solo si usa declaraciones preparadas reales (llamadas "declaraciones preparadas del lado del servidor" en la publicación de blog vinculada, que ahora es here). Por lo que debe establecer PDO :: ATTR_EMULATE_PREPARES a falso, así:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

Por último, asegúrese de que no se ha establecido PDO :: ATTR_STRINGIFY_FETCHES true.

$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); 
+6

Tenga en cuenta que el tipo 'DECIMAL' se enviará como una cadena incluso con esta configuración. Usando 'mysqlnd' versión 5.0.10 aquí. – Pere

+1

@Pere que se hace a propósito para evitar que el decimal se convierta en una flotación poco confiable en PHP. –

1

Es posible que tenga mysqlnd instalado, pero no significa que esté listo para su uso por la extensión regular de PDO(pdo_mysql), este es el caso más frecuente en alojamiento compartido, así que asegúrese de habilitar la extensión nd_pdo_mysql, y también para deshabilitar otra extensión pdo_mysql ya que podría crear un conflicto.

@screenshot

enter image description here

me encontré con esto (por duplicado) question, decidió publicar mis pensamientos aquí, espero su fina;)

Cuestiones relacionadas