PHP開発では、MySQLデータベースからバイナリデータを読む必要がある状況に遭遇することがよくあります。特に、バイナリフィールド(バイナリ、 Varbinary 、またはビットタイプなど)がデータベースに保存されている場合、これらのデータを10進値に正しく変換する方法が比較的一般的な問題になります。 PHPは、バイナリ文字列を10進整数に変換するためのBINDEC関数を提供しますが、それらを直接使用するときにいくつかの落とし穴に遭遇することがよくあります。
この記事では、bindec関数を使用してMySQLから取得したバイナリフィールドデータを処理する方法を詳細に説明します。
データベースにそのようなフィールド定義があるとします。
CREATE TABLE example (
id INT PRIMARY KEY,
bin_data BINARY(4)
);
バイナリデータの保存:
INSERT INTO example (id, bin_data) VALUES (1, 0b1011);
PHPでPDOまたはMySqliを照会する場合、 BIN_DATAフィールドは文字列として返されますが、この時点の文字列はテキスト「1011」または「11」ではなく、対応するバイトストリームではなく、バイナリコンテンツです。
たとえば、取り出した後、 「\ x0b \ x00 \ x00 \ x00」のような生のバイトである可能性があり、 Bindecを直接呼び出す結果は間違っています。
Bindec関数の引数は、「1011」のような文字列でなければなりません。バイナリバイトストリームを直接与えると、バイト値を解析することはありませんが、文字で解釈してエラー結果が得られます。
PHPの組み込み関数を使用して、バイトで「0」および「1」文字列に変換し、 Bindecで解析します。
サンプルコード:
<?php
// から想定します MySQL バイナリフィールドが削除されました
$binaryData = "\x0B"; // 小数11,対応するバイナリ1011
// バイトストリームをバイナリ文字列に変換します
function binaryToBitString(string $binary): string {
$bitString = '';
for ($i = 0; $i < strlen($binary); $i++) {
// ord() 文字を取得します ASCII コード,に変換します8ビットバイナリ文字列
$bitString .= str_pad(decbin(ord($binary[$i])), 8, '0', STR_PAD_LEFT);
}
return $bitString;
}
$bitString = binaryToBitString($binaryData);
echo "Bit string: " . $bitString . "\n";
// 使用 bindec 转换为小数数
$decimalValue = bindec($bitString);
echo "Decimal value: " . $decimalValue . "\n";
?>
出力結果:
Bit string: 00001011
Decimal value: 11
これにより、MySQLから取得したバイナリデータが10進数に正しく変換されます。
フィールドがビットタイプの場合、クエリするときにMySQL関数を使用して小数点以下に変換できます。たとえば
SELECT id, BIN(bin_data) AS bin_str FROM example;
または、整数に直接変換します。
SELECT id, CONV(HEX(bin_data), 16, 10) AS decimal_value FROM example;
このようにして、PHP側に直接取得するのは、バイナリバイトストリームの複雑な処理を避けるために、文字列の形のバイナリまたは小数です。
Bindec関数は、「0」と「1」で構成されるバイナリ文字列のみを処理でき、バイナリバイトストリームをサポートしていません。
MySQLから取得したバイナリフィールドは通常、バイトストリームであり、 Bindecを使用する前にバイナリ文字列に変換する必要があります。
自分でバイトバイト変換機能を記述することも、SQLクエリ中に関数前処理を使用することもできます。
バイナリデータの誤解を避けるために、実際の状況に従って適切な処理計画を選択します。