|
 |
Путь: >
Общие вопросы
Общие вопросы
Автор: - Crocodile
Дата публикации - 21.5.2005
Просмотров: - 3302
Поразрядные операции в PHP
[p]Предистория:[/p]
Не я конечно же первый придумал поразрядные операции, но по моим личным наблюдениям очень мало кто использует эту, на мой взгляд, весьма полезную вещь в своих разработках. Лично мне кажеться, что это из-за того что у начинающих возникают определенные трудности в первую очередь с пониманием сути поразрядных операций, при этом более опытные, возможно не видят неоходимости их применения.
Применять же эти методы очень удобно, когда необходима возможность хранения и обработки неопределенного заранее количества данных. В книге "PHP4 разработка WEB-приложений" (Т.Ратшиллер, Т.Геркен) рассмативается вариант с хранением в базе всех увлечений пользователя используя единственное поле типа INT.
[p]Немного теории[/p]
Ни для кого наверное не станет откровением что в двоичной системе счисления используется понятие октета битов - полседовательности из восьми двоичных цифр, которые и образовывают байт.
Существуют понятия "позиция бита" и "значение бита", при чем позиции бита принято нумеровать от 0 до 7-ми. Нумеруются биты с права на лево. 0-й бит (разряд) называется "младшим", 7-й, соответсвенно, старшим.
Значение бита может быть либо 0 либо 1 (false - true).
Число 24 в двоичной системе счисления имеет вид 00011000, т.е. в нем биты 4 и 5 установлены в 1, а все остальные в 0. Для перевода чисел из десятичной в двоичную форму и наоборот в PHP существуют функции DecBin() и BinDec() соответственно.
[p]Возможные операции и их применение[/p]
Поразрядные операции позволяют нам изменять значение одного или нескольких конкретных битов в числе.
[b]Чаще всего применяются следующие поразрядные операции:[/b]
[b]Установка значения (включающая дизъюнкция)[/b]
Эта опреация позволяет установить (сделать значение равным 1) определенный бит. В PHP эта опреации реализуется выражением "значение1" | "значение2", где "значение1" - есть исходное число, а "значение2" - константа определяемая как 2 в степени N, где N - номер устанавлимаего бита. Допустим необходимо установить значение бита с номером $n переменной $value, тогда строка будет иметь вид:
[code]
<?php
$newvalue=$value | (pow(2,$n));
?>
[/code]
[b]Переключение бита (исключающая дизъюнкция)[/b]
Эта опреация позволяет изменить значение конкретного бита на противоположное. Реализуется эта операция выражением "значение1" ^ "значение2", где "значение1" - есть исходное число, а "значение2" - константа определяемая как 2 в степени N, где N - номер устанавлимаего бита. Так, если необходимо переключить значение бита с номером $n переменной $value, тогда строка будет иметь вид:
[code]
<?php
$newvalue=$value ^ (pow(2,$n));
?>
[/code]
[b]Проверка значения бита (коньюнкция)[/b]
Эта опреация (&) сравнивает 2 значения и возвращает 1 для тех позиций где где биты в обоих числах равны 1. Например, чтобы проверить установлен ли бит с номером $n в переменной $value нужно использовать следующий код:
[code]
<?php
if ($value & (pow(2,$n)) {
//Соответствующий код
}
?>
[/code]
[b]Поразрядный сдвиг[/b]
Эта опреация позволяет сдвигать биты влево (<<) и вправо (>>) на конкретное количество позиций. Например, чтобы сдвинуть биты на $n позиций влево в переменной $value используем следующий код:
[code]
<?php
$newvalue = $value << $n;
?>
[/code]
[nb]Следует обратить внимание что приоритет поразрядных операций ниже, чем приоритет арифметических операций и операторов сравнения![/nb]
[p]Применение поразрядных операций для обработки информации[/p]
Одним из примеров использования поразрядных операций может являться вариант с хранением типа доступа пользователя к чему либо.
Я, лично, применяю эти операции в системе авторизации пользователей для доступа к сети Internet.
Итак, возможные типы доступа к Internet у меня подразделяются на:
Почтовый (порты 25,110)
HTTP (порт прокси 8080)
FTP (порты 20,21)
NNTP (порт 119)
Неудобно было бы для каждого из четырех параметров делать отдельное поле в БД, поэтому было принято решение использовать поразрядные операции и хранить всю информацию в одном поле типа smallint. Таким образом при формировании запроса нам нужно правильно сформировать это самое число, для чего разбираем пришедшие чекбоксы:
[code]
<?php
$type_dostup=0;
if (!empty($_POST["email"])) {
$type_dostup = $type_dostup ^ pow (2,0);
}
if (!empty($_POST["http"])) {
$type_dostup = $type_dostup ^ pow (2,1);
}
if (!empty($_POST["ftp"])) {
$type_dostup = $type_dostup ^ pow (2,2);
}
if (!empty($_POST["nntp"])) {
$type_dostup = $type_dostup ^ pow (2,3);
}
?>
[/code]
Таким обюразом мы устанавливаем значение первых 4 бит в нужные нам значения.
При проверке же (в скрипте открытия доступа) все может выглядеть примерно так:
[code]
<?php
$result=pg_query($conn,sprintf("SELECT types FROM dostups WHERE id=%d", $_SESSION["uid"]));
$type=pg_fetch_assoc($result,0);
if (1 & $type["types"]) {
//Формирование соответствующих правил
}
if (2 & $type["types"]) {
//Формирование соответствующих правил
}
if (4 & $type["types"]) {
//Формирование соответствующих правил
}
if (8 & $type["types"]) {
//Формирование соответствующих правил
}
?>
[/code]
Ну вот, в принципе, наверное и все. Тема конечно очень обширна, но основные методы были показаны и только опыт и эксперимент может дать нужный результат.
Обсудить в ФОРУМе - комментариев ()
Путь: >
Общие вопросы
Если вы заметили орфографическую, стилистическую или другую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
|
|