私はbit(1)フィールドを使用してブール値を格納し、PDOプリペアドステートメントを使用してテーブルに書き込みます。
これはテストテーブルです:
CREATE TABLE IF NOT EXISTS `test` (
`SomeText` varchar(255) NOT NULL,
`TestBool` bit(1) NOT NULL DEFAULT b'0'
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
これはテストコードです:
$pdo = new PDO("connection string etc") ;
$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES (?,?)') ;
$statement->execute(array("TEST",0)) ;
そのコードを実行すると、TestBoolの下に値1の行が表示されます。そして、bindValue()とbindParm()を使用した同じこと。 (?の代わりに)名前付きプレースホルダーも試しましたが、同じ結果になりました。
それから私は試しました:
$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES ("TEST",0)') ;
$statement->execute() ;
これは正しく機能しました(TestBoolの値は0です)。 SQLをMySQLに直接パンチすることもできます。
1を挿入すると常に機能することに注意してください。
では、なぜプレースホルダーは値0を挿入できないのでしょうか。 (そして私は実際にそれをどのように行うのですか?)
BIT列はmysqlのバイナリ型であり(数値型として文書化されていますが、正確には正しくありません)、クライアントライブラリの問題(PDOの問題で証明されています)のために回避することをお勧めします。列のタイプをTINYINT(1)に変更すると、多くの問題を回避できます。
もちろん、TINYINT(1)はすべての行で1バイトのストレージを消費しますが、mysqlのドキュメントによるとBIT(1)も同様に消費します。
差出人: http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html
ビットストレージ要件は次のとおりです。約(M + 7)/ 8バイト。これは、BIT(M)列もバイトアラインされていることを示しています。
また、私はこれを見つけました: https://bugs.php.net/bug.php?id=50757
したがって、次のコードが期待どおりに機能するかどうかを確認できます。
$pdo = new PDO("connection string etc") ;
$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES (:someText,:testBool)') ;
$statement->bindValue(':someText', "TEST");
$statement->bindValue(':testBool', 0, PDO::PARAM_INT);
$statement->execute();
PARAM_INTとは異なるタイプのヒントを試すこともできますが、それでも機能するようにしたとしても、TINYINTに変更することをお勧めします。
pdoは、デフォルトではmysqlドライバー用のプリペアドステートメントを使用せず、バックグラウンドで動的SQLを作成することによってそれらをエミュレートします。 mysqlに送信されるSQLは、最終的に「0」のように一重引用符で囲まれた0になります。これは、mysqlが数値ではなく文字列として解釈します。
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
これで機能するはずです。また、実際に準備されたステートメントを使用することになります。
prepare
はパラメータに'
を追加するため、パラメータ名の前にb
を追加するだけで済みます。
$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES (?, b?)');
$statement->execute(array("TEST", 1 /* or TRUE */));
注:1, 0
またはTRUE, FALSE
を使用できます。
あなたはパラメータなしでこれを試すことができます
if($_POST['bool'] == 1)
{
$bool = "b'1'";
}
else
{
$bool = "b'0'";
}
$statement = $pdo->prepare("INSERT INTO `test` (SomeText,TestBool) VALUES (?,$bool)") ;
$statement->execute(array("TEST")) ;
セキュリティ上の問題はありません