PHP PDO :: bindParam () tipi di dati .. come funziona?
-
08-07-2019 - |
Domanda
Mi chiedo quale sia la dichiarazione del tipo di dati in bindParam ( )
(o bindValue ()
) è utilizzato per ...
Voglio dire, ho pensato che se definissi un argomento intero ( PDO :: PARAM_INT
), l'argomento deve essere convertito in un numero intero, qualcosa come
$delete->bindParam(1, $kill, PDO::PARAM_INT);
// should work like
$delete->bindParam(1, (int)$kill);
o almeno genera un errore se l'argomento non è del tipo dichiarato. Ma non è così.
Cercando su Google, l'ho trovato nell'archivio php.net:
Ciao a tutti,
Attualmente sto lavorando a DOP. Esattamente sulla funzione bindParam (). Il terzo il parametro data_type sembra essere qui forzare il tipo di 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 un PHP errore o un interger nel mio database. Ma nel mio DB ho:
22 Testarossa Ferrari 23 250 GTO Ferrari
Significa che non è cambiato se io avere il terzo parametro o no. O forse mi manca qualcosa. Qualcuno può mi hai fregato di più? O semplicemente qualcuno mi ha detto dove posso trovare informazioni a riguardo.
Saluti,
Cyruss
Questa è esattamente la mia situazione. Dove stanno andando i miei pensieri?
Soluzione
In altri framework di astrazione di DB in altre lingue, può essere utilizzato per cose come assicurarsi che si stia eseguendo la escape corretta per i valori in-lining (per i driver che non supportano i parametri di associazione corretti) e migliorare l'efficienza della rete rendendo certo che i numeri siano opportunamente impacchettati in binari (dato il supporto del protocollo). Sembra che in DOP, non faccia 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 dici che è un STR (o se non dici niente in quanto quello è il default) e il tipo interno dei tuoi dati è un doppio, lo trasformerà in una stringa usando un metodo, se non è un doppio quindi lo convertirà in una stringa usando un metodo diverso.
Se dici che è un int ma è davvero un bool, lo convertirà in un lungo.
Se dici che è un bool ma è davvero un numero, lo convertirà in un vero booleano.
Questo è davvero tutto ciò che ho visto (rapidamente) guardando la fonte stmt, immagino che una volta passati i parametri nel driver possano fare ulteriore magia. Quindi, immagino che tutto ciò che ottieni sia un po 'di fare il giusto e un sacco di ambiguità comportamentale e varianza tra i conducenti.
Altri suggerimenti
Quindi ho deciso di immergermi nel codice sorgente di PHP e questo è quello che ho trovato.
static int really_register_bound_param
in ext / pdo / pdo_stmt.c sulla linea 329 della 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 che DOP esegue durante l'associazione.
- PDO :: PARAM_STR converte qualunque cosa tu gli dia in una stringa tranne null.
- DOP :: PARAM_INT converte i bool in long
- DOP :: PARAM_BOOL converte i long in bool
Questo è tutto. Nient'altro viene convertito. PDO utilizza i flag PARAM per formattare SQL per non trasmettere tipi di dati.
Esiste almeno un effetto DOP :: PARAM_INT ha sulle query INSERT : i 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); }
Ho provato la stessa cosa con BindValue e ho ottenuto lo stesso risultato, quindi il comportamento che stai vedendo non si limita 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();