2009-05-07 12 views
28

mi chiedo che cosa la dichiarazione del tipo di dati in bindParam() (o bindValue()) viene utilizzato per ...PHP DOP :: bindParam() tipi di dati .. come funziona?

Voglio dire, ho pensato che se io definisco come argomento un intero (PDO::PARAM_INT), l'argomento deve essere convertito a un numero intero, ad esempio

$delete->bindParam(1, $kill, PDO::PARAM_INT); 
// should work like 
$delete->bindParam(1, (int)$kill); 

o almeno lanciare un errore se l'argomento non è del tipo dichiarato. Ma questo non è il caso.

Googling intorno, ho scoperto che nell'archivio php.net:

Ciao a tutti,

Attualmente sto lavorando sulla DOP. Esattamente sulla funzione bindParam(). Il terzo parametro data_type sembra essere qui per forzare il tipo del valore? Ma quando provo:

$sql = "INSERT INTO produit (idproduit, nom, marque) VALUES (NULL, :nom, :marque)"; 
$stmt = $dbh->prepare($sql); 
$nom = 'Testarossa'; $marque = 'Ferrari' ; 
$stmt->BindValue(':marque',$marque) ; 
$stmt->BindParam(':nom',$nom,PDO::PARAM_INT) ; 

$stmt->execute(); $nom = '250 GTO' ; 
$stmt->execute(); ?> 

mi aspettavo di avere sia un errore di PHP o un numero intero nel mio database. Ma nel mio DB ho:

22 Testarossa Ferrari 250 GTO 23 Ferrari

E significa che non cambia se ho ho il terzo parametro o meno. O forse mi manca qualcosa. Può qualcuno aggiungermi di più? O semplicemente qualcuno può dirmi a dove posso trovare informazioni su .

saluti,

Cyruss

Questo è esattamente la mia situazione. Dove sono i miei pensieri che stanno andando male?

+1

"Mi aspettavo di avere un errore PHP o un interger nel mio database." anche io – VolkerK

risposta

30

in altri ambiti di astrazione DB in altre lingue che possono essere usati per cose come fare in modo che si sta facendo la giusta fuga per i valori in-rivestimento (per i driver che non supportano i parametri di corretta legati) e il miglioramento l'efficienza della rete assicurandosi che i numeri siano impacchettati in modo appropriato (dato il supporto del protocollo). Sembra in PDO, non fa molto.

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) { 
       if (Z_TYPE_P(param->parameter) == IS_DOUBLE) { 
         char *p; 
         int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter)); 
         ZVAL_STRINGL(param->parameter, p, len, 0); 
       } else { 
         convert_to_string(param->parameter); 
       } 
     } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { 
       convert_to_long(param->parameter); 
     } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) { 
       convert_to_boolean(param->parameter); 
     } 

Quindi, se si dice che è una STR (o se dite niente affatto come quello è il default) e di tipo interno dei vostri dati è una doppia poi si trasformerà in una stringa utilizzando un metodo, se non è un doppio, lo convertirà in una stringa usando un metodo diverso.

Se si dice che è un int ma è davvero un bool poi lo convertirà in un lungo.

Se si dice che è un bool ma è davvero un numero, lo convertirà in un vero booleano.

Questo è tutto ciò che ho visto (rapidamente) guardando la sorgente stmt, immagino che una volta passati i parametri nel driver, possono fare magie aggiuntive. Quindi, immagino che tutto quello che ottieni sia un po 'di fare il giusto e un sacco di ambiguità e varianza del comportamento tra i conducenti.

+1

Doh, ho postato un ninja. Suppongo che rispondo lentamente ^^. – gradbot

+0

Accidenti, pensavo fuggisse./Esecuzione a casa per correggere il codice. –

+0

Ah ok, ho trovato http://php.net/manual/en/pdo.prepared-statements.php no wories. –

5

C'è almeno un effetto PDO :: PARAM_INT ha sul INSERT query: valori booleani vengono convertiti in 0 o 1. Come in

$i = true; 
$stmt->bindParam(':i', $v, PDO::PARAM_INT);

pdo_stmt.c:

else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { 
     convert_to_long(param->parameter); 
}

+1

Oh ... mi chiedo se questo effetto sia davvero utile .. e altri data_typeS? stringa, ecc.? – Strae

+0

Non ho trovato documentazione affidabile per queste funzionalità. Quindi potrei passare attraverso tutto il codice in/ext/pdo * ... o semplicemente non fare affidamento su quel parametro per le query INSERT, UPDATE .... – VolkerK

+0

Ok, proverò sulle query SELECT per vedere se il 'problema' affligge anche loro ... Triste, comunque, che la dichiarazione data_type sarebbe utile anche per la disinfezione/controllo del flusso nelle query INSERT . – Strae

3

ho provato la stessa cosa con BindValue e ottieni lo stesso risultato in modo che il comportamento che stai vedendo non sia limitato a bindParam.

$stmt->BindValue(':marque', $marque) ; 
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ; 

$stmt->execute(); 
$nom = '250 GTO'; 
$stmt->BindValue(':nom', $nom, PDO::PARAM_INT) ; 
$stmt->execute(); 
19

Così ho deciso di immergermi nel codice sorgente PHP e questo è quello che ho trovato.

static int really_register_bound_param in ext/PDO/pdo_stmt.c sulla linea 329 dalla versione 5.2.9

if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) { 
    if (Z_TYPE_P(param->parameter) == IS_DOUBLE) { 
     char *p; 
     int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter)); 
     ZVAL_STRINGL(param->parameter, p, len, 0); 
    } else { 
     convert_to_string(param->parameter); 
    } 
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_INT && Z_TYPE_P(param->parameter) == IS_BOOL) { 
    convert_to_long(param->parameter); 
} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL && Z_TYPE_P(param->parameter) == IS_LONG) { 
    convert_to_boolean(param->parameter); 
} 

Queste sono le conversioni DOP fa durante vincolante.

  • PDO: PARAM_STR converte tutto ciò che viene assegnato a una stringa tranne null.
  • DOP :: PARAM_INT converte Caccio in anela
  • DOP :: PARAM_BOOL converte anela in Caccio

Questo è tutto. Nient'altro viene convertito. PDO utilizza i flag PARAM per formattare SQL e non trasmettere tipi di dati.

+0

"PDO: PARAM_STR converte tutto ciò che viene assegnato a una stringa" tranne NULL –