質問

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のいずれかが期待されていました   データベース内のエラーまたはinterger。   しかし、私のDBには:

があります      

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

     

それは、私が変わっても変わらなかったことを意味します   3番目のパラメーターがあるかどうか。または   たぶん何かが恋しいです。誰かできますか   もっと私を助けた?またはただ誰かができます   どこで情報を見つけられるか教えてくれた   それについて。

     

よろしく、

     

サイラス

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

役に立ちましたか?

解決

他の言語の他の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に変換されます。

boolであるが実際には数値であると言う場合、真のブール値に変換します。

これは、実際にstmtソースを(すばやく)見たすべてです。ドライバーにパラメーターを渡すと、追加の魔法ができると思います。だから、あなたが得るのは、少しだけ正しいことと、ドライバー間の行動のあいまいさと分散の多くです。

他のヒント

だから私はPHPソースコードに飛び込むことにしました。これが私が見つけたものです。

static int really_register_bound_param ext / pdo / pdo_stmt.cのバージョン5.2.9の329行目

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

これらは、バインディング中にPDOが行う変換です。

  • PDO :: PARAM_STRは、指定したものをnull以外の文字列に変換します。
  • PDO :: PARAM_INTはboolをlongに変換します
  • PDO :: PARAM_BOOLはlongをブールに変換します

それだけです。それ以外は変換されません。 PDOはPARAMフラグを使用して、データ型をキャストしないようにSQLをフォーマットします。

INSERT クエリに対するPDO :: PARAM_INTの影響は少なくとも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);
}

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(); 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top