PHP вопрос о побитовом - PullRequest
1 голос
/ 19 июля 2011

У меня есть такой скрипт

$job = array(
        1 => 'User',
        2 => 'Editor',
        4 => 'Supervisor',
        8 => 'Manager',
        10 => 'President');

$value = 18;

foreach($job as $key => $val)
{
   if($value & $key)
   {
      $job[] = $key;
      echo $val.', ';
   }
}

Теперь я хочу добиться того, чтобы в приведенном выше примере «18» система отображала только значение «Менеджер, Президент» (10 + 8 = 18;)

Но если вы запустите скрипт, система отобразится как редактор, президент,

это не все массивы, которые у меня есть, у меня есть еще 23 значения массива

Извините, но я действительно не могу объяснить это по-английски, надеюсь, вы понимаете ...

Ответы [ 4 ]

3 голосов
/ 19 июля 2011
<?php

  $flags = array(
    1   => 'User',       // 00000001 Note the place of the 1
    2   => 'Editor',     // 00000010
    4   => 'Supervisor', // 00000100
    8   => 'Manager',    // 00001000
    16  => 'President'   // 00010000
  );

  // permission we're going for
  $permissions = 16 + 8; // 00011000  again, note the 1's places.

  $levels = array();
  foreach ($flags as $level => $name)
  {
    if (($permissions & $level) == $level)
      $levels[] = $name;
  }
  echo implode(', ', $levels);

Выход:

Manager, President

Вы хотите, чтобы ваши значения имели степень 2, чтобы в двоичном коде соответствующий флаг совпадал с указанным вами разрешением.

Битовое И (&) говорит (когда оно достигает Менеджер ):

    $flags     $Pemissions   $flags
if (00001000 & 00011000) ==  00001000
if       (00001000)      ==  00001000 [true]

По сути, если флаг установлен с обеих сторон (как значение, которое вы проверяете, так и против), сохраните этот бит. Затем убедитесь, что оно по-прежнему равно значению, которое вы проверяете. Если это так, пользователь получает это разрешение. AND имеет значение true, только когда оба левые и правые значения имеют установленные биты.

1 голос
/ 19 июля 2011

Ваша проблема в том, что 10 не является переменной 2 ^ y.

10 = 2 + 8 (2 ^ 1 и 2 ^ 3), и, следовательно, будет соответствовать значениям 2 и 8 соответственно.

Если вы хотите разрешить побитовый выбор, как вы делаете;вам нужно , чтобы выбрать 2 ^ y значений для ваших индексов (1, 2, 4, 8, 16, 32 и т. д.).

Затем вы можете безопасно добавить эти значения в качестве селекторов (например,16 + 4 (20), 2 + 32 (34) и т. Д.)

1 голос
/ 19 июля 2011

Значение для президента неверно.Чтобы использовать битовое поле, все числа должны быть степенями двух, поэтому Президент должен быть 16, а не 10.

Обратите внимание, что 16 (десятичное) равно 0x10 (шестнадцатеричное) - возможно, установив значение Президента в 10 (десятичное)была ошибка копирования / вставки?

0 голосов
/ 19 июля 2011

Вы должны изменить 10 на 16 (1,2,4,8,16,32, ..), иначе вы можете не понять какое-то число. 10 = 10 или 10 = 2 + 8

...