У меня есть таблица в базе данных MySQL с BIT(64)
строка, которая является битовой маской из 64 флагов.
Используя PHP и MySQL, у меня есть целое число $n
, который находится в диапазоне [0, 64)
, Я уже написал функцию (см. Приложение I) установить пго бит байтового массива (то есть строка в PHP).
При передаче вышеупомянутого байтового массива (строки) в MySQL кажется, что bitmask & ?
, где ?
является mysqli::bind_param
редактируется как байтовый массив (тип параметра "s"
), не сравнивает биты, как ожидалось.
Например, используя этот запрос:
SELECT id FROM my_table WHERE (bitmask & ?) > 0
на этом столе:
CREATE TABLE my_table (id INT PRIMARY KEY, bitmask BIT(64));
Как это можно исправить?
Я думал о передаче bin2hex
а также UNHEX()
это, но это, кажется, не решает проблему.
public static function setNthBit(int $n, int $bytes = 8) : string{
$offset = $n >> 3;
$byteArray = str_repeat("\0", $bytes);
$byteArray{$bytes - 1 - $offset} = chr(1 << ($n & 7));
return $byteArray;
}
Похоже, что проблема возникает из-за того, что MySQL не поддерживает побитовое сравнение строк. Когда я передаю битовую маску как параметр напрямую, MySQL пытается интерпретировать ее как целое число, например пытаясь интерпретировать bitmask & '123'
как bitmask & 123
, Я не уверен, как MySQL интерпретирует кучу двоичных символов, таких как \xFF
или же \x00
— это просто не будет работать, вероятно, интерпретируется как 0.
Я решил это, передав bin2hex
битовой маски на входе, а затем CONV(?, 16, 10)
в запросе. CONV () будет выражать данные в десятичном формате, который MySQL будет интерпретировать как, мы надеемся, что-то вроде BIGINT, который может быть успешно побитовым по сравнению со строкой BIT (64).
Других решений пока нет …