MySQL选择位(1)显示为字符串(3)

ZZ-*_*-bb 4 php mysql bit

我有一个包含列的表bit(1)和以下查询:SELECT my_bit FROM my_table.

当我echophp页面上显示结果时,该值显示为string(3) %qu 列上的位值是0还是1.这怎么可能?

以下查询解决echoing了网页上的问题:SELECT CAST(my_bit AS UNSIGNED) AS my_bit FROM my_table.

但是,上述两个查询都适用于命令行工具.不,string(3)那里.

选择数据时一切正常,两者之间没有区别

  1. SELECT*FROM my_table WHERE my_bit = 0
  2. SELECT*FROM my_table WHERE my_bit =(0)

使用命令行工具或Web界面php页面时.(这里建议使用后者.)Echoing必须使用CAST函数完成,但WHERE不受parentehis的影响:返回正确的行.

主要问题

  1. 为什么返回的bit类型值是否echoed相同,string无论bit值是0还是1?
  2. 使用bit(1)类型列插入/选择数据时是否有任何特殊问题需要考虑?(快速测试表明一切都按预期工作:0插入0和1插入1,但我可能会遗漏一些东西.)

我正在使用MAMP在本地测试:PHP 5.3.2和MySQL 5.1.44.命令行工具是指Sequel Pro(不是MAMP的PhpAdmin).Php页面utf-8和查询使用SET NAMES 'utf8'.


更新:代码

CREATE TABLE `my_table` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `my_bit` bit(1) NOT NULL,
  PRIMARY KEY (`id`,`lto_muu`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci;

INSERT INTO `my_table` (`id`, `my_bit`) VALUES (null, 0), (null,1)

//php page
//query option 1
SELECT `id`, `my_bit`  FROM `my_table`
//query option 2
SELECT `id`, CAST(`my_bit` AS UNSIGNED) AS `my_bit`  FROM `my_table`

$mysqli = new mysqli("localhost", "root", "root","my_db");
$q = "SELECT `id`, `my_bit`  FROM `my_table`";//returns 2 rows

$r = $mysqli->query($q);

while($row = mysqli_fetch_array($r,MYSQLI_ASSOC)){
echo 'id: ' . $row['id'] . ' - bit: ' . $row['my_bit'] . '<br />';
}
Run Code Online (Sandbox Code Playgroud)

查询选项1打印出来:

id: 1 - bit: %qu
id: 2 - bit: %qu
Run Code Online (Sandbox Code Playgroud)

查询选项2打印出来:

id: 1 - bit: 0
id: 2 - bit: 1
Run Code Online (Sandbox Code Playgroud)

更新2:Álvaro的代码

$conn = new mysqli('localhost', 'root', 'root','test');
//$mysqli->set_charset('utf8');
$conn->query('DROP TABLE IF EXISTS bit_test');
$conn->query('CREATE TABLE bit_test (
    my_bit BIT(1) NULL,
    my_multiple_bit BIT(8) NULL
)');
$conn->query("INSERT INTO bit_test (my_bit, my_multiple_bit) VALUES (b'0', b'111')");
$conn->query("INSERT INTO bit_test (my_bit, my_multiple_bit) VALUES (b'1', b'10000000')");

//opt 1
$q = 'SELECT cast(my_bit as unsigned) as my_bit, my_multiple_bit FROM bit_test';
//opt2 
//$q = 'SELECT my_bit, my_multiple_bit FROM bit_test';
$r = $conn->query($q);
while($row = mysqli_fetch_array($r, MYSQLI_ASSOC)){
    echo bin2hex($row['my_bit']) . '<br />';
    echo bin2hex($row['my_multiple_bit']) . '<br />';
    var_dump($row);
    echo '<br /><br />';
}
Run Code Online (Sandbox Code Playgroud)

使用PHP 5.2.12 opt 1和2都打印:

30
07
array(2) {
  ["my_bit"]=>
  string(1) "0"
  ["my_multiple_bit"]=>
  string(1) ""
}
31
80
array(2) {
  ["my_bit"]=>
  string(1) "1"
  ["my_multiple_bit"]=>
  string(1) "?"
}
Run Code Online (Sandbox Code Playgroud)

使用PHP 5.3.2 opt 1打印:

30
257175
array(2) {
  ["my_bit"]=>
  string(1) "0"
  ["my_multiple_bit"]=>
  string(3) "%qu"
}
31
257175
array(2) {
  ["my_bit"]=>
  string(1) "1"
  ["my_multiple_bit"]=>
  string(3) "%qu"
}
Run Code Online (Sandbox Code Playgroud)

并选择2:

257175
257175
array(2) {
  ["my_bit"]=>
  string(3) "%qu"
  ["my_multiple_bit"]=>
  string(3) "%qu"
}
257175
257175
array(2) {
  ["my_bit"]=>
  string(3) "%qu"
  ["my_multiple_bit"]=>
  string(3) "%qu"
}
Run Code Online (Sandbox Code Playgroud)

PHP 5.3.2 alvays打印%qu.这有意义吗?

ZZ-*_*-bb 8

简短的回答

好的,这是我自己的问题的简短答案.如果要确保将bit(1)列作为整数检索,请在检索bit(1)值时使用以下查询:

$q = 'SELECT (my_bit + 0) AS my_bit, (my_multiple_bit + 0) AS my_multiple_bit FROM bit_test';

如果未使用"+ 0",则将bit(1)列的值视为binary string. 这是我对自己说"RTM"的那一刻......

通过谷歌的魔力在这里找到类似的东西......

如果您对快速解决方案感到满意,请立即停止阅读.

现在凌乱/冗长的答案(让我们使用Álvaro的代码)

让我们创建表并使用四个不同的查询,在我的MAMP安装上有两个PHP版本:5.3.2和5.2.12.

$conn = new mysqli('localhost', 'root', 'root','my_db');

$conn->query('DROP TABLE IF EXISTS bit_test');
$conn->query('CREATE TABLE bit_test (
    my_bit BIT(1) NULL,
    my_multiple_bit BIT(8) NULL
)');

$conn->query("INSERT INTO bit_test (my_bit, my_multiple_bit) VALUES (b'0', b'111')");
$conn->query("INSERT INTO bit_test (my_bit, my_multiple_bit) VALUES (b'1', b'10000000')");

//q1
$q = 'SELECT (my_bit + 0) AS my_bit, (my_multiple_bit + 0) AS my_multiple_bit FROM bit_test';
//q2
//$q = 'SELECT cast(my_bit as unsigned) as my_bit, my_multiple_bit FROM bit_test';
//q3
//$q = 'SELECT HEX(my_bit) AS my_bit , HEX(my_multiple_bit) AS my_multiple_bit FROM bit_test';
//q4
//$q = 'SELECT my_bit, my_multiple_bit FROM bit_test';

$r = $conn->query($q);

//let's echo a few options
//plain gives unaltered result
//bin2hex gives hexadecimal number of an ASCII string (since) the values are treated as strings
//base16to10 gives decimal representation of hexadecimal value
//yes, the two functions are contradictionary (dependable of the query in use)
//but I'll echo their result anyway
while($row = mysqli_fetch_array($r, MYSQLI_ASSOC)){
  echo 'plain: ' . $row['my_bit'] . '<br />';
  echo 'plain: ' . $row['my_multiple_bit'] . '<br />';
  echo 'bin2hex: ' . bin2hex($row['my_bit']) . '<br />';
  echo 'bin2hex: ' . bin2hex($row['my_multiple_bit']) . '<br />';
  echo 'base16to10: ' . base_convert($row['my_bit'],16,10) . '<br />';
  echo 'base16to10: ' . base_convert($row['my_multiple_bit'],16,10) . '<br />';
  var_dump($row);
  echo '<br /><br />';
}
Run Code Online (Sandbox Code Playgroud)

以下是不同查询的结果

我真正感兴趣的是普通输出var_dump,但你也可以检查bin2hexbase16to10输出在查找数字是否有一些链接到相应的值时很有用:数字0,7,1和128(存储的值)分为bit表格的四列).

q1 - 安全投注 - 输出在PHP 5.3.2和5.2.12中是相同的

plain: 0
plain: 7
bin2hex: 30
bin2hex: 37
base16to10: 0
base16to10: 7
array(2) { ["my_bit"]=> string(1) "0" ["my_multiple_bit"]=> string(1) "7" }

plain: 1
plain: 128
bin2hex: 31
bin2hex: 313238
base16to10: 1
base16to10: 296
array(2) { ["my_bit"]=> string(1) "1" ["my_multiple_bit"]=> string(3) "128" }
Run Code Online (Sandbox Code Playgroud)

q2 - 输出的一些差异

工作正常,bit(1)my_multiple_bit输出中的某些内容非常错误.

PHP 5.2.12:
plain: 0
plain: 
bin2hex: 30
bin2hex: 07
base16to10: 0
base16to10: 0
array(2) { ["my_bit"]=> string(1) "0" ["my_multiple_bit"]=> string(1) "" }

plain: 1
plain: ?
bin2hex: 31
bin2hex: 80
base16to10: 1
base16to10: 0
array(2) { ["my_bit"]=> string(1) "1" ["my_multiple_bit"]=> string(1) "?" } 
Run Code Online (Sandbox Code Playgroud) PHP 5.3.2
plain: 0
plain: %qu
bin2hex: 30
bin2hex: 257175
base16to10: 0
base16to10: 0
array(2) { ["my_bit"]=> string(1) "0" ["my_multiple_bit"]=> string(3) "%qu" }

plain: 1
plain: %qu
bin2hex: 31
bin2hex: 257175
base16to10: 1
base16to10: 0
array(2) { ["my_bit"]=> string(1) "1" ["my_multiple_bit"]=> string(3) "%qu" }
Run Code Online (Sandbox Code Playgroud)

q3 - PHP 5.3.2和5.2.12中的输出相同

这也是一个安全的查询.只记得将检索到的十六进制转换为十进制数.

plain: 0
plain: 7
bin2hex: 30
bin2hex: 37
base16to10: 0
base16to10: 7
array(2) { ["my_bit"]=> string(1) "0" ["my_multiple_bit"]=> string(1) "7" }

plain: 1
plain: 80
bin2hex: 31
bin2hex: 3830
base16to10: 1
base16to10: 128
array(2) { ["my_bit"]=> string(1) "1" ["my_multiple_bit"]=> string(2) "80" }
Run Code Online (Sandbox Code Playgroud)

q4 - 输出很奇怪

PHP 5.2.12可以正常使用,bit(1)但如果对使用的PHP版本或它的行为有任何疑问,我不会使用此查询.

PHP 5.2.12
plain:
plain: 
bin2hex: 00
bin2hex: 07
base16to10: 0
base16to10: 0
array(2) { ["my_bit"]=> string(1) "" ["my_multiple_bit"]=> string(1) "" }

plain: 
plain: ?
bin2hex: 01
bin2hex: 80
base16to10: 0
base16to10: 0
array(2) { ["my_bit"]=> string(1) "" ["my_multiple_bit"]=> string(1) "?" } 
Run Code Online (Sandbox Code Playgroud) PHP 5.3.2
plain: %qu
plain: %qu
bin2hex: 257175
bin2hex: 257175
base16to10: 0
base16to10: 0
array(2) { ["my_bit"]=> string(3) "%qu" ["my_multiple_bit"]=> string(3) "%qu" }

plain: %qu
plain: %qu
bin2hex: 257175
bin2hex: 257175
base16to10: 0
base16to10: 0
array(2) { ["my_bit"]=> string(3) "%qu" ["my_multiple_bit"]=> string(3) "%qu" } 
Run Code Online (Sandbox Code Playgroud)

最后的想法和自我注意

RTM,再次测试和测试.

也很高兴知道这个%qu输出是否是一个独家的PHP 5.3.2错误.(或者其他PHP版本会受到影响.)

所以,Álvaro的答案在使用CAST或检索HEXDB中的值时是正确的.该手册显示了额外的"+0"方法,似乎从不同的PHP版本行为中消除了痛苦.因此简短的回答是最重要的...