세션을 DB로 관리하기 + 쪽지 확인하기

[1] 대개의 경우, 회원 로그인에 세션을 사용합니다. 즉 회원으로 로그인하지 않으면 세션을 사용할 일이 없는 경우가 많습니다. 따라서 여기서는 회원 전용 세션만 관리하도록 하겠습니다.

[2] 세션 테이블을 만들어서, 여기에 매번 insert, delete를 하는 것은 비록 테이블 크기가 작다고 하더라도 제법 부하를 줍니다. 따라서 여기서는 delete를 쓰지 않고 update만 사용하도록 하겠습니다. 회원이 몇만명이라고 할지라도 이게 더 나은 것 같더군요.

세션 테이블을 다음과 같이 만듭니다. 회원목록 테이블과 똑같은 rows를 갖게 되겠죠.
CREATE TABLE `user_sessions` (
`uid` int(10) unsigned NOT NULL default ‘0’, /* 회원ID */
`sess_key` varchar(32) NOT NULL default ”, /* 세션키 */
`last_log` int(11) unsigned NOT NULL default ‘0’, /* 세션을 기록하는 시간 */
`last_ip` varchar(15) NOT NULL default ”, /* 꼭 필요하지는 않지만, 추후 필요성을 느끼게 될 것임 😉 */
`sess_value` text NOT NULL, /* 세션값 */
PRIMARY KEY (`uid`),
KEY `sess_key` (`sess_key`)
) TYPE=MyISAM;

세션을 처리하는 스크립트는 다음과 같습니다.
(편의상 DB 클래스를 사용했습니다만, 뭐하는건지는 다 아시겠죠? –;;)

session_set_save_handler(“sess_open”, “sess_close”, “sess_read”, “sess_write”, “sess_destroy”, “sess_gc”);
session_start();

function sess_open($save_path, $session_name) {
return 1;
}

function sess_read($key) {
$DB =& DB::getInstance();
$DB->query(“SELECT sess_value FROM user_sessions WHERE sess_key = ‘$key’ AND last_log > ‘”.(time()-get_cfg_var(“session.gc_maxlifetime”)).”‘ “);
$row=$DB->get();
return $row[0];
}

function sess_write($key, $value) {
$DB =& DB::getInstance();
$DB->query(“UPDATE user_sessions SET last_log='”.time().”‘, last_ip='”.$_SERVER[“REMOTE_ADDR”].”‘, sess_value=’$value’ WHERE sess_key=’$key’ “);
return ”;
}

function sess_close() {
return 1;
}

function sess_destroy($key) {
$DB =& DB::getInstance();
$DB->query(“UPDATE user_sessions SET sess_key=”, last_log='”.time().”‘, last_ip='”.$_SERVER[“REMOTE_ADDR”].”‘ WHERE sess_key=’$key’ “);
}

function sess_gc($lifetime) {
return 1;
}

[3] 회원 로그인하는 부분에서 sess_key 값을 할당합니다. 그 다음부터 그 회원은 세션 테이블에서 데이타를 읽고 쓸 수 있습니다.
비회원인 경우는 session_start()를 하더라도 세션키값만 주어질 뿐, 여러가지 $_SESSION값을 사용할 수 없습니다. (물론 쿠키값을 이용해 비회원의 경우는 아예 session_start()를 실행하지 않는 방법도 있죠. ^^;;)

[4] 이렇게 함으로써 굳이 가비지 콜렉션(update 혹은 delete)을 하지 않아도 됩니다. 또 회원의 마지막 접속시간이 최신으로 유지됩니다.

[5] 회원의 중복 로그인이 방지됩니다. 다만, 같은 위치에서 다른 세션을 다시 시작하는 경우인지, 이미 로그인된 상태인지 등의 예외적 상황을 처리하기 위해 로그인을 처리하는 부분을 보강해야겠죠. 😉

——————————
자, 이쯤에서 한가지 욕심을 내어볼까요? 이른바, 쪽지 기능을 추가해보겠습니다. (실시간 쪽지 기능 아닙니다. –;;)
제로보드인가? 쪽지를 받으면 “딩동, 새로운 메시지가 도착했습니다” 하는 소리가 나쟎아요.
받은 쪽지 테이블을 따로 만들면, 매번 해당 테이블을 읽어야 하지 않습니까. 뭐 굳이 2번 작업을 하냐, 세션을 시작하면서 자동적으로 그 데이타를 읽어오자 하는거지요.

`user_sessions` 테이블에 chk_msg 라는 필드를 하나 추가합니다.
ALTER TABLE `user_sessions` ADD `chk_msg` TINYINT(2) UNSIGNED NOT NULL AFTER `last_ip` ;
다른 회원이 쪽지를 보낼때, chk_msg 값을 하나씩 증가시키고, 쪽지를 확인하면 chk_msg 값을 0로 update하려는 것입니다.

sess_read 함수를 변형시켜서, chk_msg 필드값을 읽어오도록 합니다.
function sess_read($key) {
$DB =& DB::getInstance();
$DB->query(“SELECT uid, chk_msg, sess_value FROM user_sessions WHERE sess_key = ‘$key’ AND last_log > ‘”.(time()-get_cfg_var(“session.gc_maxlifetime”)).”‘ “);
$row=$DB->get();
$GLOBALS[“USER”][“id”]=$row[0];
$GLOBALS[“USER”][“chk_msg”]=$row[1];
return $row[2];
}

여기서는 $USER라는 변수에 회원ID, 받은쪽지 갯수를 저장하도록 했습니다. 즉 회원ID를 알기 위해 $_SESSION[“id”]를 쓰지 않고 $USER[“id”]를 쓸 수 있다는 거지요. 받은 쪽지 갯수는 $USER[“chk_msg”]에 들어가니까 매번 이 값을 검사해서 “딩동~ 메시지가 도착했습니다” 라고 알려주면 됩니다.

“뭐야, 난데없이 $USER 라는 글로벌 오브젝트라니…. 난 이런거 싫어” 하시는 분.
여기서 $USER와 같은 변수를 할당하지 않고, $_SESSION을 사용해도 됩니다. $USER[“chk_msg”]=”1″ 대신에 $_SESSION[“chk_msg”] = “1” 이라고 써도 된다는 겁니다. 세션함수 안에서 $_SESSION을 사용한다니, 황당한 트릭이죠? 번거롭게 세션값($row[2])을 직접 파싱할 필요가 없습니다.
다만, 이것은 맨처음 1번만 적용됩니다. 다음번에 $_SESSION[“chk_msg”] = “2” 라고 하더라도, 이미 세션 데이타 안에 “chk_msg”값이 1로 들어있기 때문에, 결과는 “1”로 나옵니다. 따라서 $_SESSON[“chk_msg”] 값을 확인해서 “딩동~” 하는 메시지를 보여주거나 말거나 한 후에, 매번 unset($_SESSION[“chk_msg”])를 해줘야하겠죠?

——————————

재미있으셨나요?
“한번 더 생각하고 DB를 만들자”는 취지에서 한번 써봤고, 나름대로 효율적이라고 생각하는데… 장담은 못하겠네요. 오류나 정정사항은 리플 부탁드립니다.

TEXTAREA에서 탭키 사용하기


다중연동셀렉트(3단) 폼소스 (출처 : 야후)

간단히 설명드리면 IOS라는 폼에 ind,job,spe 세가지 셀렉트를 가지고
위계적으로 서로 관계를 설정하여 동작시키고 있습니다.

====================================================================================




*각종단체(범주):

*각종단체(종류):
*예시단체:


주민등록번호 실명 확인 함수

/****************************************************
**
** 주민등록번호 실명 확인
**
** input : $name : 성명
** $rrn1 : 주민등록번호 앞 6자리
** $rrn2 : 주민등록번호 뒤 7자리
** $date : 주민등록증 발급일
**
****************************************************/
function check_resident( $name, $rrn1, $rrn2, $date )
{

$target = “http://www.egov.go.kr/main?a=AA090UserRrnCheckApp&” .
“user_nm=” . $name . “&” .
“rrn1=” . $rrn1 . “&” .
“rrn2=” . $rrn2 . “&” .
“date=” . $date;
$str = @file( $target );
if( !$str ) return false; // 접속 실패;

$check = 0;
$count = 0
$str_len = sizeof( $str );
for( $i=0; $i<$str_len; $i++ )
{
$c_str = Chop( $str[$i] );
if( eregi( ““, $c_str ) ) $check = 1;
if( eregi( ““, $c_str ) ) break;
if( $check == 1 ) $count ++;
if( $count == 6 )
{
$c_str = Chop( strip_tags( $c_str ) );
$message = $c_str;
return( “$message” );
}

}

}

PhpCollab – 실무그룹웨어툴(한글파일유)

=====================================================================

1.사이트: http://www.phpcollab.com/phpbb/index.php
2.이용싸이트: http://www.phpcollab.com/phpbb/viewforum.php?f=2
3.데모: http://www.phpcollab.com/phpbb/viewforum.php?f=3&sid=bfb76a126fc505e1c57f115efe10f344
4.다운로드: http://www.phpcollab.com/phpbb/viewforum.php?f=9&sid=bfb76a126fc505e1c57f115efe10f344
6.지원포럼: http://www.phpcollab.com/phpbb/viewforum.php?f=4&sid=bfb76a126fc505e1c57f115efe10f344
7.저자소개: St?hane DION
8.라이센스: 무료(GPL)
9.플랫폼: Windows, Linux, MacOs X
10.버전/용량: 2.4/891KB

======================================================================

소 개
그릅웨어모듈, 팀공동웹프로젝트관리, 사용자관리, 직무와프로젝트 트렉킹,
파일승인트렉킹, 프로젝트사이트 크라이언트접근, 고객관련관리등.

======================================================================

설치
1. 웹폴더(예:phpcollab)내에 모든파일을 풉니다.

2. Unix/Linux 는 includes/settings_blank.php 파일명을 includes/settings.php
파일명으로 바꾸어 주세요.

3. 다음 폴더와 파일을 777 로 chmod 합니다.
– includes/settings.php (파일)
– files (폴더)
– logos_clients (폴더)

4. 원하는 디비를 생성합니다.

5. installation/setup.php 을 실행해 서버환경에 맞게 매개변수를셋팅합니다.
– 테이블접두어는 빈칸입니다(디비하나만 쓰는사람은 원하는 접두어를
쓰는것이 좋습니다 예: “phppollab_ ” ).

6. 설치완료후 설치파일을 삭제하시고 로그인하시면 됩니다.
주의: 로그인 정보요구시 사용자명도 같이 입력하고 나옵니다. 일단은
” admin ” 비번은 설치시 입력한것으로 들어간후 후에 변경하세요.

————————————————
기타 세부설정등은 install.txt 파일을 참고하세요
————————————————-

1115766557.tgz