사랑스런 아가에게….

건강아!
엄마는 아침부터 부지런을 떨었단다. 뭐냐구?
화분에 물을 듬뿍 주었지. 잎도 닦아주고, 화분주위에 묻어있는 흙도 말끔히 닦아내고..
그랬더니 이쁜 화초들이 더 이쁘고 파릇해보이는거 있지.
날씨가 참 좋거든.
집에만 있기엔 너무 아까운 날씨이긴 하지만, 그래도 엄마는 집에서 느껴야겠구나.
우리 앞집이 며칠전에 지붕을 새단장했걸랑.
파란색으로 기와를 다시 입혔는데 날씨가 너무 화창해서인지 그 빛이 더 파랗단다.

현관문을 열고 한발짝 내딛게 되면 계단 오른쪽으로 쪼르륵 크고 작은 화분들이 줄지어 있고,
고개를 들어 오른쪽 먼 정경을 보노라면 너른 논과 작은 동산이 한눈에 들어온단다.
풍요롭구나..
이젠 제법 물이 올라 초록이 더 초록으로 되버렸거든.
며칠전부터 오전 오후로 아저씨 한분이 큰 기계를 끌고 그 너른 논을 종횡무진하시더니 이미 모내기가 끝나 있구나. 흥건히 물이 고인 논바닥에 깊이 박힌 모들이 잦은 바람에 흔들거린단다.
아침에 문을 열고 오른쪽으로 눈을 돌렸을때-파란하늘과 초록대지, 상쾌한 공기, 맑은 햇살
그리고 들려오는 참새와 까치소리…
우리 건강이하고 엄마가 느끼는 풍경이란다.
참, 왼편으로는 이미 그 탐스런 꽃잎이 져버린 목련의 잎이 점점 커져 엄마 손바닥보다
커졌구나.풍성한 나무로 변신을 했지.
조금 있으면 부엌으로 난 창틀에 올려놓은 조그만 화분에서는 채송화꽃이 필거야.
앙증맞은 채송화는 그 빛깔도 색색이 곱단다.
이제 얼마 안남았지?
우리 건강이에게도 직접 보여줄게. 그 동안은 엄마의 눈과 마음과 감성으로 느꼈겠지만,
이젠 그 풍요로움을 직접 볼 수 있게될거야.
조금만 기다리렴.
윗집에서 김치찌개를 끓이는가보다. 이미 아침을 먹었건만 구수한 찌개냄새가 엄마의 왕성한
식욕을 자극하는구나.

어제는 엄마가 무엇을 했는지 궁금하지? 건강이 옷과 기저귀를 빨았단다.
얼마전 할머니 이모할머니, 고모 그리고 건강이 외숙모께서 사주신 옷이며 기저귀며
양말이며..
볕이 너무 좋아서 뽀드득 마르라고 어제 빨았단다.
두개의 빨래걸이에 널려있는 새하얀 기저귀와 앙증맞은 옷, 양말들이 어쩜 그리 이쁠까..
바람이 살랑 불때마다 날리는 모습만 봐도 기분이 좋아지더구나.
혹, 바람에 그 여린 것들이 떨어질까봐 엄마는 수시로 문을 열고 내다보았지.
뽀송뽀송 잘 마른 그것들을 개어서 서랍장에 정리하고 난 후의 뿌듯함..
말로 표현하기 힘들다.
저녁에 아빠가 퇴근하셨을 때 잘 정돈된 건강이 옷가지들을 보여드렸더니 아빠도 무지
기뻐하셨단다.
참 그제는 아빠께서 ‘인어공주’동화를 읽어주셨는데, 우리 건강이 잘 들었지?
아빠가 덜 피곤하시면 우리 건강이를 위해 더 많은 책을 읽어주실텐데, 일하시느나
피곤하셔서 자주 못하사는거니까 건강이가 아빠를 이해해드리렴.
아빠께서 건강이를 사랑하시는 맘은 정말 크거든…

오늘은 건강이 베개에 십자수를 빨랑 놓아야겠다. 턱받이는 이미 끝나서 걸어놓았는데…
빨리 완성해서 우리 아가에게 보여줄게.

아까 시골에 계신 외할아버지와 통화를 했는데 외할아버지 목소리에 기운이 없으시더구나.
외할아버지는 연세가 많으시단다. 힘내시라고, 건강하시라고, 오래오래 사셔서 건강이
재롱 보시라고 우리 건강이가 힘을 드리렴.

사랑한다. 사랑스런 우리 아가~~~

——마음 따뜻한 사람이 되었으면 하는 바램으로—– 엄마가..

세션을 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를 만들자”는 취지에서 한번 써봤고, 나름대로 효율적이라고 생각하는데… 장담은 못하겠네요. 오류나 정정사항은 리플 부탁드립니다.

[수정] 번개수정합니다

에구구.. 다들 5월은 바쁜가보네요.
그래서 내린 결정이..
6월초로 연기하기로 했습니다. 6월초가 지나면 내가 힘들것 같고해서요

예정일은 6월5일 목요일 (현충일 바로 전날이지요) – 부담없을것 같아서..

6월7일 토요일보다는 낫겠죠? 그럼 그때 꼭 시간들 비워두세요~~~~~

시간은 항상 그대로일거고..

자세한 공지는 그때쯤 다시 올리렵니다.