2009-07-28 15 views
53

Sto usando PDO e MySQL, per qualche motivo quando ottengo valori dal database che sono di tipo int, il PDOStatement restituisce una rappresentazione di stringa del numero e non un valore di tipo numerico. Come posso evitare che ciò accada?Come ottenere tipi numerici da MySQL usando PDO?

Ho notato che esiste un attributo della classe PDO: PDO::ATTR_STRINGIFY_FETCHES che dovrebbe occuparsi di ciò ma, quando si tenta di modificarlo, genera un errore che dice che l'attributo non è valido per il driver MySQL.

È normale ottenere stringhe anziché numeri quando si consulta un database?

risposta

37

Non credo che avere "i numeri" può essere fatto in PHP 5.2 :-(

In PHP 5.3, diventa possibile, se non ricordo male, quando si utilizza il nuovo (nuova come in PHP> = 5.3) mysql ND(MySQL Native driver) conducente

Ebbene, dopo più scavando attraverso i miei segnalibri ho trovato questo articolo su mysqlnd:. PDO_MYSQLND: The new features of PDO_MYSQL in PHP 5.3

Si dice questo (citazione):

I vantaggi dell'utilizzo di mysqlnd per i prodotti DOP

mysqlnd restituisce tipi di dati nativi quando usare codice lato server prepared statement, ad esempio una colonna INT viene restituito come variabile intera non come stringa . Ciò significa un minor numero di conversioni di dati internamente.

Ma questo è solo PHP 5.3 (fornito la propria versione di PHP 5.3 è compilato con mysqlnd (e non vecchio libmysql)), e sembra essere solo il caso per le istruzioni preparate :-(

Scusa ...

Una soluzione sarebbe avere, sul lato PHP, un sistema di mappatura (come un ORM - vedere Doctrine; proprio come un esempio di ORM: non so se lo fa cosa stai chiedendo) per convertire i risultati provenienti dai tipi di dati DB in PHP ...

E sì, questo è male se si desidera utilizzare gli operatori come === e !==, che sono di tipo sensibile ...

+7

Su Ubuntu provare 'sudo apt-get install php5-mysqlnd ' – Alex

+0

Anche io dovevo fare quello che @Alex ha detto qui per avere php mysqlnd sotto il cofano. +1 per il suo commento. – Zugwalt

+0

Avanti veloce al 2016, per avere i tipi di dati corretti restituiti da MySQL, per PHP 7 su CentOS/RHEL: 'yum install php70w-mysqlnd' –

55

Per rispondere alla tua ultima domanda prima, "sì", purtroppo è normale per ricevere i numeri come stringhe. Come dice il manuale citato da Pascal, mysqlnd (PHP 5.3) restituirà i tipi di dati nativi dalle istruzioni preparate, a condizione di disattivare l'emulazione di istruzione preparata da PDO.

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

PDO: ATTR_STRINGIFY_FETCHES non è correlato a MySQL.

Se si guarda il lato positivo, è buona norma utilizzare istruzioni preparate comunque, quindi ...;)

+2

questa è la risposta vincente ^.^ – naomik

+0

Concordato. Questa è l'unica risposta che ha funzionato per me. Grazie. –

+0

chiaramente la risposta vincente – eightyfive

24

Pascal's answer è corretto.Ho avuto qualche problema a far funzionare tutto. Ecco cosa devi fare.

Prima di tutto, assicurati di avere mysqlnd installato e attivato. Guarda php --info. Nella sezione pdo_mysql, dovrebbe assomigliare:

pdo_mysql 

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

Se invece di vedere mysqlnd nella versione Client API, si vede una linea come ...

Client API version => 5.5.29 

... allora si don' t avere mysqlnd installato e funzionante. Prenditi cura di questo prima.

In secondo luogo, PDO utilizza le istruzionidi istruzioni preparate emulate. Ridicolo, ma è così. E otterrai tipi di dati nativi solo se utilizzi istruzioni preparate reali (chiamate "istruzioni preparate sul lato server" nel post del blog collegato, che ora è here). Quindi, è necessario impostare DOP :: ATTR_EMULATE_PREPARES su false, in questo modo:

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

Infine, assicurarsi che non si è impostato DOP :: ATTR_STRINGIFY_FETCHES su true.

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

Nota che il tipo 'DECIMAL' sarà ancora inviato come stringa anche con questa configurazione. Usando 'mysqlnd' versione 5.0.10 qui. – Pere

+1

@Pere che è fatto apposta per evitare che il decimale diventi un float inaffidabile in PHP. –

1

si potrebbe avere mysqlnd installato, ma non significa che è pronto per l'uso da parte del regolare PDO estensione (pdo_mysql), questo è più spesso il caso in hosting condiviso, quindi assicuratevi di attivare l'estensione nd_pdo_mysql, e anche per disabilitare l'altra estensione pdo_mysql in quanto potrebbe creare un conflitto.

@screenshot

enter image description here

ho trovato questo (duplicato) question, ha deciso di postare i miei pensieri qui, la speranza la sua fine;)