Я использую phpBB в качестве платформы форума. Я использую сервер Mutualised Linux с PHP версии 5.6.31 и MySQL (i) 5.7.19-log.
И я обнаружил ошибку, которая не возникает на других серверах, поскольку некоторые члены команды phpbb, как и мой друг, не могли воспроизвести проблему. Но есть больше людей с той же проблемой.
Для людей, которые хотят проверить сами:
В основном с новой установкой phpBB 3.2.1 мы можем перейти на ACP — Forums — Ваша первая категория — Ваш первый форум.
Там мы подтвердили, что опция «Включить быстрый ответ» помечена как «Нет». Затем мы переходим к ACP — Отправка сообщений — Настройки сообщений и нажимаем «Отправить и включить быстрый ответ на всех форумах».
После этого мы снова идем на «ваш первый форум», чтобы проверить «Включить быстрый ответ» и он по-прежнему отображается как «Нет».
И это должно быть «Да».
Я попытался отладить и .php-файл, который имеет функцию, которая будет создавать запрос SQL, который будет отправлен в базу данных, я поставил:
печать (1 << 6); и это дает мне 64.
Так что я тоже поставил: print ($ bit); и это дает мне 6.
Итак, код (1 << $ bit), который находится на php, должен быть правильным и должен дать мне 64 НО, если я поставлю: print (1 << $ Бит); это дает мне 32!
Я поставил 3 отпечатка:
print(1 << 6);
print($bit);
print(1 << $bit);
И результат был: 64 6 32
Wtf ?! Какого черта, когда у нас есть переменная со значением 6, она принимает значение 5?!, Или она принимает в качестве 6-й позиции представление байта?
У кого-нибудь есть идеи, почему это происходит? Может быть PHP баг версии? Или любой тип конфигурации может связываться с этим?
Позвольте мне объяснить лучше.
В /includes/constants.php мы можем найти:
define('FORUM_FLAG_QUICK_REPLY', 64);
Это значение будет использоваться для создания значения $ bit.
И на /includes/acp/acp_board.php у нас есть функция, которая создаст переменную $ bit:
$config->set($config_name, $config_value);
if ($config_name == 'allow_quick_reply' && isset($_POST['allow_quick_reply_enable']))
{
enable_bitfield_column_flag(FORUMS_TABLE, 'forum_flags', log(FORUM_FLAG_QUICK_REPLY, 2));
}
Эта функция _enable_bitfield_column_flag_ создаст SQL-код.
И журнал (FORUM_FLAG_QUICK_REPLY, 2) = Log2 (64) = 6.
Вот почему бит $ равен 6.
И в включает / functions_admin.php мы в:
function enable_bitfield_column_flag($table_name, $column_name, $flag, $sql_more = '')
{
global $db;
$sql = 'UPDATE ' . $table_name . '
SET ' . $column_name . ' = ' . $db->sql_bit_or($column_name, $flag) . '
' . $sql_more;
$db->sql_query($sql);
}
Мы можем увидеть здесь SQL-код, созданный с помощью PHP-кода.
И наконец на /phpbb/db/driver/driver.php мы в:
return $column_name . ' | ' . (1 << $bit) . (($compare) ? ' ' . $compare : '');
И перед этой строкой я поставил 3 отпечатка, и значения были 64 6 32 … и не имеет смысла, почему print $ bit дает 6 и 1 << $ bit дает 32 …
Заранее спасибо!
Основываясь на наших комментариях, и предположим, что $ bit действительно log2(64)
Я провел несколько тестов и подтвердил свою первоначальную идею:
$bit = log(64,2);
echo gettype(6)."\n"; // integer
echo gettype($bit)."\n"; // double
echo (int)$bit."\n"; // prints 6, but might as well have been 5
echo round($bit)."\n"; // prints 6
демо здесь: https://3v4l.org/Zogme
В этой демонстрации все проверенные версии php приводят к приведению результата к 6 при преобразовании в целочисленный тип (как в случае с побитовыми операторами сдвига, такими как <<
, который работает с целочисленными аргументами), но это не гарантировано.
Значения с плавающей запятой / double не очень безопасны для работы, лучше округляйте их явно до целого числа, просто чтобы быть уверенным и избежать ошибки, которую вы видите.
$bit = round($bit);
Престижность идет к @axiac для проверки фактов и подталкивает меня написать это как ответ. Дайте мне знать, если я смогу улучшить его.
Других решений пока нет …