제목 비트연산으로 다중값 처리하기
등록자 미랑 등록일시 2009-11-23 조회수 212 HIT
출처 : PHPSCHOOL
원본링크 : http://phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=23650


만들어 쓰고 있던 함수입니다.

폼에서 어떤 설정들을 다중으로 선택받고 싶을 때 사용하면 좋습니다.

예: 당신이 소지한 카드들을 선택해 주세요.
form 에서:
<form name=f>
<input type=checkbox name="card_is[]" value="0x00001"> 삼성
<input type=checkbox name="card_is[]" value="0x00002"> LG
<input type=checkbox name="card_is[]" value="0x00004"> 현대
<input type=checkbox name="card_is[]" value="0x00008"> 국민
<input type=checkbox name="card_is[]" value="0x00010"> 외환
...
<input type=checkbox name="card_is[]" value="0x01000"> 경남
</form>

php에서:
<?
$arr_card = array(
0x00001 => '삼성카드',
0x00002 => 'LG카드',
0x00004 => '현대카드',
0x00008 => '국민카드',
0x00010 => '외환카드',
0x00020 => '한미카드',
0x00040 => '기업카드',
0x00080 => '하나카드',
0x00100 => '기타BC카드',
0x00200 => '전북카드',
0x00400 => '동아백화점카드',
0x00800 => '롯데백화점카드',
0x01000 => '경남카드'
);

//bit
function bit_get($_fld) {
global ${"$_fld"};
$fld = ${"$_fld"};
if(!is_array($fld)) {
${"$_fld"} = 0;
return 0;
}
$tmp = 0;
foreach($fld as $k=>$v) {
$tmp = $tmp | (0+$v);
}
${"$_fld"} = $tmp;
}

function bit_str($bit,$arr,$sep="") {

if(!is_array($arr)) return NULL;

$cnt = count($arr);
$b = 1; $str = ""; $cnt_match =0;
for($n=0;$n<$cnt;$n++) {
if($b & $bit) {
if($cnt_match>0)
$str .= $sep;
$str .= $arr[$b];
$cnt_match ++;
}
$b <<= 1;
}
return $str;
}

$card_is = bit_get("card_is"); // 원래의 변수를 다중 선택된 비트값의 변수로 재사용.

echo bit_str($card_is,$arr_card_is,$sep=",") // 선택한 카드를 , 로 구분하여 리턴.
?>

입력은 이렇게 받으면 되고, 수정할 때 다시 원래의 카드를 선택하는 건
아래 요령입니다.

<form name=f>
<input type=checkbox name="card_is[]" value="0x00001"
<?=(0x00001 & $card_is)?"checked":""?>> 삼성
<input type=checkbox name="card_is[]" value="0x00002"
<?=(0x00002 & $card_is)?"checked":""?>> LG
<input type=checkbox name="card_is[]" value="0x00004"
<?=(0x00003 & $card_is)?"checked":""?>> 현대
...
<input type=checkbox name="card_is[]" value="0x01000"
<?=(0x01000 & $card_is)?"checked":""?>> 경남
</form>

그렇다면 검색(목록에서..) 할 때는... ?
$find_card_is = 0x0001 | 0x0003 | 0x01000 ;
이 값은 삼성,lg,경남 카드 선택하는 것이구...
select * from table where card_is & $find_card_is;

이렇게 하시면, card_is 에 설정된 비트중 $find_card_is 의 비트와 하나라도 맞으면 찾아집니다.

select * from table where card_is & ~ $find_card_is;
--> 하나도 일치하지 않을 때.

select * from table where (card_is & $find_card_is) = $find_card_is;
--> 모두가 일치할 때.

-- jeon.




 
====================================================
유림님 댓글 (03-10-08 18:28)  
====================================================

상당히 유용할 것 같아서.. 클래스로 쪼금 묶어봤습니다.
기본 데이터 컨테이너를 Array 로 했습니다. (다른점)

아래 아이템은 절대루 순서가 바뀌어서도
중간에 이빨이 나가두 안됨
아래에 계속 추가는 할 수 있음

$arr_card = array(
 null, // \"삼성카드\", 아이템 삭제시 null 로 대치
 \"LG카드\",
 \"현대카드\",
 \"국민카드\",
 \"외환카드\",
 \"한미카드\",
 \"기업카드\",
 \"하나카드\",
 \"기타BC카드\",
 \"전북카드\",
 \"동아백화점카드\",
 \"롯데백화점카드\",
 \"경남카드\"
);

class ArrayBitHandler {
 var $_items;
 function ArrayBitHandler($keys) {
  if(!isset($keys) || !is_array($keys) || count($keys) > 32) {
   // 2^32 보다 크면 대략 낭패 : PHP 의 interger
   // throw exception
  }
  $this->_items = array();
  $value = 1;
  foreach($keys as $key) {
   if(isset($key)) { $this->_items[(string)$key] = $value; }
   $value *= 2;
  }
 }

 function getValue($keys) { // int getValue(mixed keys)
  $rv = 0;
  if(is_array($keys)) {
   foreach($keys as $key) {
    $rv += $this->getValue($key);
   }
  } else { // string 으로 간주
   return (array_key_exists((string)$keys, $this->_items))?
       $this->_items[(string)$keys] : 0;
  }
  return $rv;
 }

 function getKey($values) { // array getKey(int values)
  $rv = array();
  foreach($this->_items as $key => $value) {
   if($value & $values) { $rv[$value] = $key; }
  }
  return $rv;
 }
}


$a = new ArrayBitHandler($arr_card);

$a->getValue(array(\"LG카드\", \"현대카드\"));
$a->getValue(\"국민카드\");

$a->getKey(15));

$a->getKey(array_sum($_POST[\"card_id\"])); // 본문의 예제 HTML 에서. 

목록보기

        X  
38  위치고정 배너스크롤  2009-12-23 151
37  비트연산의 응용  2009-11-23 180
 비트연산으로 다중값 처리하기  2009-11-23 212
35  다른 페이지에서 임의의 스트립트 실행하기  2009-11-23 155
34  웹페이지 소스보기와 드래그가 안 될 경우  2008-02-27 161
33  마우스 오버시 텍스트 링크 부분의 설명을 창으로  2008-02-16 156
32  팝업 공지 쿠키 설정  2006-11-26 178
31  새 창 띄우기 옵션 (window.open)  2006-11-25 145
30  스크롤 게시물 (솔로몬닷컴 방식)  2006-05-28 107
29  동적으로 textarea 추가하기  2006-05-26 142
28  강추! 셀렉트 박스 스타일 수정  2006-05-03 134
27  금액에 점찍고 한글 표시하기...  2006-05-03 147
26  마우스 클릭시 창 하단의 링크 주소 감추기  2006-05-03 179
25  팝업창 띄우기 옵션 및 방법  2006-05-02 148
24  주소를 입력받아서 이동하는 스크립트  2006-05-02 128
1 2 3