31

bindParam()(または)のデータ型の宣言は何にbindValue()使用されているのでしょうか...

つまり、整数の引数(PDO::PARAM_INT)を定義する場合、引数は次のような整数に変換する必要があると思いました。

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

または、引数が宣言されたタイプでない場合は、少なくともエラーをスローします。しかし、そうではありません。

グーグルで調べてみると、php.netアーカイブで次のことがわかりました。

こんにちは、みんな、

私は現在PDOに取り組んでいます。まさにbindParam()関数です。3番目のパラメーターdata_typeは、値の型を強制するためにここにあるようです。しかし、私が試してみると:

$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(); ?>

データベースにPHPエラーまたは整数が含まれていると予想していました。しかし、私のDBには:

22テスタロッサフェラーリ23250GTOフェラーリ

これは、3番目のパラメーターがあるかどうかに関係なく変更されなかったことを意味します。または多分私は何かが恋しいです。誰かが私をもっと苦しめることができますか?または、誰かが私にそれに関する情報を見つけることができる場所を教えてもらえますか?

よろしく、

サイラス

それがまさに私の状況です。私の考えはどこで間違っていますか?

4

4 に答える 4

32

他の言語の他の DB 抽象化フレームワークでは、インライン化された値 (適切なバインドされたパラメーターをサポートしていないドライバーの場合) に対して適切なエスケープを行っていることを確認したり、数値が適切にバインドされていることを確認してネットワーク効率を向上させたりするために使用できます。適切にパックされたバイナリ (プロトコルをサポートしている場合)。PDOのように見えますが、あまり機能しません。

   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);
        }

したがって、それが STR であると言う場合 (または、それがデフォルトであるため何も言わない場合) で、データの内部型が double の場合、1 つのメソッドを使用して文字列に変換されます。double でない場合は、別の方法を使用して文字列に変換します。

int であると言い、実際には bool である場合は、long に変換されます。

ブール値であると言ったが、実際には数値である場合、真のブール値に変換されます。

stmt のソースを (簡単に) 見たのはこれだけです。パラメーターをドライバーに渡すと、追加の魔法を実行できると思います。したがって、あなたが得られるのは、ドライバー間のあいまいな動作と相違点の多くと、正しいことを少し行うことだけだと思います。

于 2009-05-14T21:43:19.390 に答える
6

PDO::PARAM_INT がINSERTクエリに対して持つ効果が少なくとも 1 つあります。ブール値は 0 または 1 に変換されます。

$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);
}

于 2009-05-07T10:49:17.163 に答える
3

BindValue で同じことを試してみたところ、同じ結果が得られたので、表示されている動作は 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(); 
于 2009-05-14T20:38:57.877 に答える