Побитовые операторы позволяют оценивать и манипулировать определенными битами в целом числе.

ExampleNameResult
$a & $bAndBits that are set in both $a and $b are set.
$a | $bOr (inclusive or)Bits that are set in either $a or $b are set.
$a ^ $bXor (exclusive or)Bits that are set in $a or $b but not both are set.
~ $aNotBits that are set in $a are not set, and vice versa.
$a << $bShift leftShift the bits of $a $b steps to the left (each step means "multiply by two")
$a >> $bShift rightShift the bits of $a $b steps to the right (each step means "divide by two")

Битовый сдвиг в PHP является арифметическим. Биты, сдвинутые с любого конца, отбрасываются. При сдвиге влево нули смещаются вправо, а бит знака смещается влево, что означает, что знак операнда не сохраняется. Сдвиги вправо имеют копии бита знака, сдвинутые влево, что означает сохранение знака операнда.

Используйте круглые скобки, чтобы обеспечить желаемый приоритет . Например, $a & $b == trueоценивает эквивалентность, затем побитовое и; в то время как ($a & $b) == trueоценивает побитовую, а затем эквивалентность.

Если оба операнда для &операторов |и ^являются строками, то операция будет выполняться над значениями ASCII символов, составляющих строки, и результатом будет строка. Во всех остальных случаях оба операнда будут преобразованы в целые числа, и результатом будет целое число.

Если операндом для ~оператора является строка, операция будет выполняться над значениями ASCII символов, составляющих строку, и результатом будет строка, в противном случае операнд и результат будут рассматриваться как целые числа.

Оба операнда и результат для операторов <<и >>всегда обрабатываются как целые числа.

Параметр PHP error_reporting ini использует побитовые значения, обеспечивая реальную демонстрацию отключения битов. Чтобы отобразить все ошибки, кроме уведомлений, инструкции к файлу php.ini говорят использовать: E_ALL & ~E_NOTICE      

Пример #1 Побитовые операции AND, OR и XOR над целыми числами

<?php
/*
 * Ignore the top section,
 * it is just formatting to make output clearer.
 */

$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
        . ' %3$s (%4$2d = %4$04b)' . "\n";

echo <<<EOH
 ---------     ---------  -- ---------
 result        value      op test
 ---------     ---------  -- ---------
EOH;


/*
 * Here are the examples.
 */

$values = array(0, 1, 2, 4, 8);
$test = 1 + 4;

echo "\n Bitwise AND \n";
foreach ($values as $value) {
    $result = $value & $test;
    printf($format, $result, $value, '&', $test);
}

echo "\n Bitwise Inclusive OR \n";
foreach ($values as $value) {
    $result = $value | $test;
    printf($format, $result, $value, '|', $test);
}

echo "\n Bitwise Exclusive OR (XOR) \n";
foreach ($values as $value) {
    $result = $value ^ $test;
    printf($format, $result, $value, '^', $test);
}
?>

Приведенный выше пример выведет:

--------- --------- -- --------- 
 значение результата op test 
 --------- -------- - -- --------- 
 Побитовое И 
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101) 
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101) 
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101) 
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101) 
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101) 

 Побитовый Включающее ИЛИ 
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101) 
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101) 
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101) 
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101) 
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101) 

 Побитовое исключающее ИЛИ (XOR) 
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101) 
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101) 
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101 ) 
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)

 

Пример #2 Побитовые операции XOR над строками

<?php
echo 12 ^ 9; // Outputs '5'

echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
                 // ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8

echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
                        // 'a' ^ 'e' = #4

echo 2 ^ "3"; // Outputs 1
              // 2 ^ ((int)"3") == 1

echo "2" ^ 3; // Outputs 1
              // ((int)"2") ^ 3 == 1
?>

 

Пример #3 Сдвиг битов для целых чисел

<?php
/*
 * Here are the examples.
 */

echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";

$val = 4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');

$val = 4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places);

$val = 4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');

$val = 4;
$places = 4;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0');


echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";

$val = -4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');

$val = -4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');

$val = -4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');


echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";

$val = 4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 4;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = 4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places, 'sign bits get shifted out');

$val = 4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side');


echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";

$val = -4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');

$val = -4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places);

$val = -4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');


/*
 * Ignore this bottom section,
 * it is just formatting to make output clearer.
 */

function p($res, $val, $op, $places, $note = '') {
    $format = '%0' . (PHP_INT_SIZE * 8) . "b\n";

    printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);

    echo " Decimal:\n";
    printf("  val=%d\n", $val);
    printf("  res=%d\n", $res);

    echo " Binary:\n";
    printf('  val=' . $format, $val);
    printf('  res=' . $format, $res);

    if ($note) {
        echo " NOTE: $note\n";
    }

    echo "\n";
}
?>