2013-04-21 14 views
12

Sto migrando i miei codici PHP da mysql (obsoleto in 5.5) a PDO_MySQL. Tuttavia, mysql_fetch_row restituisce un numero intero mentre PDOStatement::fetch restituisce le stringhe per i numeri. Come posso rendere PDO si comporta come il precedente?Perché non PDO_MySQL restituisce intero?

Risultato di mysql_fetch_row:

array(1) { 
    ["id"]=> 
    int(1) 
} 

Risultato di PDOStatement::fetch:

array(1) { 
    ["id"]=> 
    string(1) "1" 
} 

risposta

13

Impostare PDO::ATTR_EMULATE_PREPARES su false, se si ha realmente bisogno con loosely-digitato PHP

If mysql_fetch_row si ritorna Int anche per SUM (non mi è mai importato di controllare) - allora fa un po 'di magia come if (ctype_digit($val)) $row[$key] = (int)$val; - quindi puoi fare nel tuo DBAL

Per quanto ne so, il modo in cui le istruzioni preparate funzionano, utilizza la stessa struttura di pacchetto per l'invio e il recupero dei dati e questo pacchetto contiene il tipo di dati.

Sembra che il server possa restituire i dati in 2 formati: nativo e mysqlnd, dipende dal tipo di richiesta. Quest'ultimo può essere interpretato dalla libreria client per trasmettere il valore risultante.

+0

E funziona nella maggior parte dei casi, ma non funziona per 'SUM SELECT (...' Inoltre, come indica il nome, i vantaggi delle dichiarazioni preparate non saranno validi con questa opzione? – Haocheng

+0

Per chi legge questa risposta in futuro: 1) No, non ha interpretato erroneamente la domanda. 2) Sì, modifica effettivamente il tipo di dati dei valori restituiti. –

+0

@Haocheng Leggi attentamente questa frase, è doppio negativo;) –

5

Per la cronaca, DOP dispone di una funzione in grado di modificare questo, PDO::ATTR_STRINGIFY_FETCHES:

Converti valori numerici in stringhe durante il recupero. Richiede bool.

La logica alla base dell'impostazione è che i motori di database possono gestire numeri molto grandi (Oracle, ad esempio, consente numeri a 38 cifre) e PHP no. Recuperare quei numeri come stringhe è un metodo per proteggersi e prevenire la perdita di dati.

Purtroppo, the MySQL driver does not support it:.

<?php 

$pdo = new PDO('mysql:host=localhost;dbname=test', 'test', 'test'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); 
$sql = 'SELECT 1 AS integer_number, 3.14 AS floating_point'; 
$res = $pdo->query($sql); 
while($row = $res->fetch(PDO::FETCH_ASSOC)){ 
    var_dump($row); 
} 

 

array(2) { 
    ["integer_number"]=> 
    string(1) "1" 
    ["floating_point"]=> 
    string(4) "3.14" 
} 
+0

Mi piace la parte logica della risposta, anche se se ho visto correttamente in uso, il PDO MySQL non supporta 'PDO :: ATTR_STRINGIFY_FETCHES', poiché _everything_ viene restituito come un tipo di dati' string' già Ciò significa che questo attributo è abbastanza inutile con quel driver – Jon

+0

@Jon - Hai ragione, l'ho appena trovato io. Ho aggiornato la mia risposta. –

Problemi correlati