출처 : 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 에서.
|
|