Верх страницы
Обложка к записи Битовые операции в PHP на примерах
Время для прочтения: 0 мин. 42 сек.

Битовые операции в PHP на примерах

Навеяно статьей об обработке критических ошибок в PHP. Обратил внимание, что несмотря на то, что коды ошибок в PHP специально заточены под битовые операции, тем не менее, что в примерах статьи, что в комментариях, для проверки кодов ошибок используются обычные операторы сравнения.

Например, встречались такие варианты:

if ( $error['type'] == E_ERROR || $error['type'] == E_PARSE || $error['type'] == E_COMPILE_ERROR ) {...}

Или:

if ( in_array( $error['type'], array( E_ERROR, E_PARSE,  E_COMPILE_ERROR ) ) {...}

В связи с этим решил написать небольшую статью о битовых операциях с примерами их использования.

Немного теории

Число в двоичной (бинарной) системе исчисления представляет собой набор нулей и единиц. Самый правый бит, нулевой, называется младшим значащим битом (разрядом).

Например, число 5 будет выглядеть, как 00000101.

Всего в наличии 6 побитовых операторов:

  • $a & $b — И (получаем число в котором установлены биты, которые установлены в $a и в $b)
  • $a | $b — Или (получаем число в котором установлены биты, которые установлены в $a или в $b)
  • $a ^ $b — Исключающее или (число в котором установлены биты установленные в $a или в $b, но не в обоих одновременно)
  • ~$a — Отрицание (инверсия, 1 меняется на 0, и наоборот)
  • $a < < $b — Сдвиг влево (все биты в $a смещаются влево на количество позиций в $b)
  • $a >> $b — Сдвиг вправо (все биты в $a смещаются вправо на количество позиций в $b)

Практика на примерах

Для большей наглядности рассмотрим в качестве примера, простую систему разграничения прав доступа к сайту.

У нас будут доступны следующие права доступа: Чтение, Создание, Редактирование, Удаление. То есть всего 4 значения, их можно представить в виде 4-х битного числа, в котором 1 — означает, что у пользователя есть данное право, а 0 — нет.

Для наглядности нарисовал картинку.

Определим для прав доступа следующие константы:

define( 'U_READ', 1 << 0 );   // 0001
define( 'U_CREATE', 1 << 1 ); // 0010
define( 'U_EDIT', 1 << 2 );   // 0100
define( 'U_DELETE', 1 << 3 ); // 1000
define( 'U_ALL', U_READ | U_CREATE | U_EDIT | U_DELETE ); // 1111

Установка значений битов

Присваиваем одно право.

$user_perm =  U_READ; // только право чтения

Чтобы комбинировать несколько прав используем побитовый оператор ИЛИ.

$user_perm =  U_READ | U_DELETE; // можно читать и удалять

Добавляем все права с помощью заготовленной константы.

$user_perm =  U_ALL; // все права

Если нужно дать все права кроме одного или нескольких, то можно воспользоваться следующими операторами.

$user_perm =  U_ALL ^ U_DELETE;  // все права кроме  удаления
$user_perm =  U_ALL & ~ U_DELETE; // все права кроме  удаления, в данном случае 2 оператора

Разница между этими вариантами в том, что в первом случае просто переключается бит, если был 1, то станет 0, и наоборот.

Второй же вариант делает бит равным 0, независимо от его текущего значения.

Проверка значения бита

Выставлять биты мы уже научились, теперь рассмотрим как же их использовать, т.е. проверять значение. Для проверки наличия прав доступа используем побитовый оператор И.

if ( $user_perm & U_READ ) // есть ли право чтения?

Можно проверять значения сразу нескольких бит, к примеру:

if ( $user_perm & ( U_READ | U_DELETE ) ) // есть ли право чтения и/или удаления

Сброс бита

Если мы хотим убрать какое-нибудь право доступа, то пишем так:

$user_perm &= ~ U_DELETE; // запретить удаление

Послесловие

Если вернуться к проверке ошибок. То примеры из начала статьи, можно заменить на:

if( $error['type'] & ( E_ERROR | E_PARSE | E_COMPILE_ERROR ) ) {...}

Ссылки

Опубликовано с позволения автора (zapimir). Оригинал находится на Хабре.

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, OpenCart, DLE, Laravel, Moonshine, Symfony, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

2 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
anton
anton
12 лет назад

а бы почему сброс бита не вот так сделать?
$user_perm ^= U_DELETE;

mihdan
10 лет назад

С этим вопросом ван надо к zapimir обратиться — он автор статьи

Предыдущая запись

Давайте дружить
в Telegram

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы