글쓴이:우수한
mysql_fetch_object로 쿼리를 던지면, 그 결과 오브젝트(객체)를 받아오게 됩니다.
이것이 어떻게 프로그래밍을 간편하게 만들어주는지 살펴보도록 하겠습니다.
—– [1단계: 기초] —–
자, 다음과 같은 테이블이 있다고 합시다.
CREATE TABLE users (
id varchar(10) not null,
name varchar(10) not null,
addr varchar(30) not null,
phone varchar(14) not null,
PRIMARY KEY (id)
);
INSERT INTO users VALUES (“test”, “아무개”, “서울”, “02-123-4567”);
여기서는 편의상 DB 클래스를 사용하겠습니다. (하지만 DB클래스가 중요한 것은 아닙니다.)
DB->fetch()라는 함수는 mysql_fetch_object()를 뜻한다는 것만 아시면 됩니다.
$DB->query(“SELECT id, name, addr, phone FROM users WHERE id=’test’ “);
$user = $DB->fetch();
위와 같은 코드를 실행하면, 그 결과 $user->id 에는 “test”, $user->name 에는 “아무개” 등의 값이 들어있는 것을 확인하실 수 있습니다.
자, 그럼 위의 기능을 함수로 만들어보겠습니다. sugar01
회원테이블에 테스트용으로 아이디 ‘test’ 비밀번호 ‘test’ 인 데이터를 하나 넣었습니다. INSERT INTO sugar_member VALUES(”,’test’,password(‘test’)); ##########세션 관리 테이블################### $connect=mysql_connect(“$localhost”,”$user_name”,”$db_passwd”) or die(“SQL server에 연결할수 없습니다.”); include “config.php”; session_cache_limiter(”); function sess_open($save_path, $session_name) { “; function sess_read($key) { “; function sess_write($key, $value) { “;
if(mysql_num_rows($query)) else //로그아웃 하고 나가서 다시 로그인 하려는 경우 echo(“ } mysql_query($query) or die(mysql_error()); } else// 계속 로그인 해져있는상태 } return true; function sess_close() { function sess_destroy($key) { “; function sess_gc($lifetime) {
?> if($_SESSION[sess_id]!=””)
“);
“); if($mode==ok) $sql=mysql_query(“select password(‘$passwd’)”); $sql=mysql_query(“select * from sugar_member where id=’$id’&&passwd=’$conv_passwd'”) or die(mysql_error()); } echo”“; [1] 대개의 경우, 회원 로그인에 세션을 사용합니다. 즉 회원으로 로그인하지 않으면 세션을 사용할 일이 없는 경우가 많습니다. 따라서 여기서는 회원 전용 세션만 관리하도록 하겠습니다. [2] 세션 테이블을 만들어서, 여기에 매번 insert, delete를 하는 것은 비록 테이블 크기가 작다고 하더라도 제법 부하를 줍니다. 따라서 여기서는 delete를 쓰지 않고 update만 사용하도록 하겠습니다. 회원이 몇만명이라고 할지라도 이게 더 나은 것 같더군요. 세션 테이블을 다음과 같이 만듭니다. 회원목록 테이블과 똑같은 rows를 갖게 되겠죠. 세션을 처리하는 스크립트는 다음과 같습니다. session_set_save_handler(“sess_open”, “sess_close”, “sess_read”, “sess_write”, “sess_destroy”, “sess_gc”); function sess_open($save_path, $session_name) { function sess_read($key) { function sess_write($key, $value) { function sess_close() { function sess_destroy($key) { function sess_gc($lifetime) { [3] 회원 로그인하는 부분에서 sess_key 값을 할당합니다. 그 다음부터 그 회원은 세션 테이블에서 데이타를 읽고 쓸 수 있습니다. [4] 이렇게 함으로써 굳이 가비지 콜렉션(update 혹은 delete)을 하지 않아도 됩니다. 또 회원의 마지막 접속시간이 최신으로 유지됩니다. [5] 회원의 중복 로그인이 방지됩니다. 다만, 같은 위치에서 다른 세션을 다시 시작하는 경우인지, 이미 로그인된 상태인지 등의 예외적 상황을 처리하기 위해 로그인을 처리하는 부분을 보강해야겠죠. 😉 —————————— `user_sessions` 테이블에 chk_msg 라는 필드를 하나 추가합니다. sess_read 함수를 변형시켜서, chk_msg 필드값을 읽어오도록 합니다. 여기서는 $USER라는 변수에 회원ID, 받은쪽지 갯수를 저장하도록 했습니다. 즉 회원ID를 알기 위해 $_SESSION[“id”]를 쓰지 않고 $USER[“id”]를 쓸 수 있다는 거지요. 받은 쪽지 갯수는 $USER[“chk_msg”]에 들어가니까 매번 이 값을 검사해서 “딩동~ 메시지가 도착했습니다” 라고 알려주면 됩니다. “뭐야, 난데없이 $USER 라는 글로벌 오브젝트라니…. 난 이런거 싫어” 하시는 분.
—————————— 재미있으셨나요? 한솔교육의 교사를 대상으로 하는 판촉장비 지원시스템 홈페이지. 각종 태그와 php문법어들이 난무하고 있다.
function load_user($id) {
$SQL = ” SELECT * FROM users WHERE id=’$id’ “;
$DB =& DB::getInstance();
$DB->query($SQL);
return $DB->fetch();
}
이제 회원정보를 읽어올때 $user = load_user(“test”); 라고 하면 끝입니다.
회원정보를 변경할 수 있는 폼을 출력할때
디비로 세션관리 및 중복로그인 방지
http://prospect.new21.net
###########회원 테이블###########
CREATE TABLE sugar_member (
num int(4) unsigned NOT NULL auto_increment,
id char(20) NOT NULL default ”,
passwd char(20) NOT NULL default ”,
PRIMARY KEY (num)
) TYPE=MyISAM;
CREATE TABLE sugar_session4 (
uid varchar(32) NOT NULL default ‘0’,
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, //세션값, 로그인 하게되면 저장되는 정보
attack int(2) NOT NULL default ‘0’, //로그인후 다른 아이피에서 로그인 하려 하면 증가
KEY sess_key (sess_key)
) TYPE=MyISAM;
#######config.php#########
$localhost=localhost;
$user_name=””; //디비 사용이름
$db_passwd=””; //디비 패스워드
$db_name=””; //디비 이름
mysql_select_db(“$db_name”,$connect);
?>
#########sess_test.php#################
session_set_save_handler(“sess_open”, “sess_close”, “sess_read”, “sess_write”, “sess_destroy”, “sess_gc”);
session_start();
//echo”_SESSION[sess_id] = $_SESSION[sess_id]
“;
$time=time();
//echo”time= $time
“;
//echo”sess_open save_path = $save_path session_name= $session_name
return 1;
}
//echo”sess_read key = $key
$query=mysql_query(“SELECT sess_value FROM sugar_session4 WHERE sess_key = ‘$key’ AND last_log > ‘”.(time()-get_cfg_var(“session.gc_maxlifetime”)).”‘ “) or die(mysql_error());
$row=mysql_fetch_array($query);
return $row[0];
}
//echo”sess_write key = $key value=$value
$query=mysql_query(“SELECT * FROM sugar_session4 WHERE sess_key=’$key’AND sess_value IS NOT NULL”) or die(mysql_error());
$time=time();
$check=mysql_num_rows($query);
//echo”check = $check
“;
if(mysql_num_rows($query)==0) //새로 로그인 하려는 경우
{
if($value!=””)
{
$uid=$GLOBALS[‘sess_id’];
//로그아웃 하지 않고 창을 닫아서 사이트를 나가고 다시 로그인 하려는 경우
$query=mysql_query(“SELECT sess_value from sugar_session4 WHERE uid=’$uid’ AND last_ip='”.$_SERVER[“REMOTE_ADDR”].”‘”) or die(mysql_error());
{
mysql_query(“UPDATE sugar_session4 SET sess_key=’$key’,last_log='”.time().”‘, last_ip='”.$_SERVER[“REMOTE_ADDR”].”‘, sess_value=’$value’ WHERE uid=’$uid'”) or die(mysql_error());
echo”“;
}
{
//다른 아이피로 접근 하려는 경우
$query=mysql_query(“SELECT sess_value FROM sugar_session4 WHERE uid=’$uid’ AND last_ip!='”.$_SERVER[“REMOTE_ADDR”].”‘”) or die (mysql_error());
if(mysql_num_rows($query))
{
$query=mysql_query(“UPDATE sugar_session4 SET attack=attack+1 WHERE uid=’$uid’ AND last_ip!='”.$_SERVER[“REMOTE_ADDR”].”‘”) or die (mysql_error());
“);
else //순수히 새로 로그인 하려는 경우
{
$query=”INSERT INTO sugar_session4 VALUES(‘$uid’,’$key’,’$time’,'”.$_SERVER[“REMOTE_ADDR”].”‘,’$value’,”)”;
echo”“;
}
}
}
{
$query=mysql_query(“SELECT attack FROM sugar_session4 WHERE sess_key=’$key'”);
$row=mysql_fetch_array($query);
if($row[attack]!=0) echo” $row[attack] 번 다른곳에서 접속 시도가 있었습니다
“;
mysql_query(“UPDATE sugar_session4 SET last_log='”.time().”‘, last_ip='”.$_SERVER[“REMOTE_ADDR”].”‘, sess_value=’$value’ WHERE sess_key=’$key’ “) or die(mysql_error());
}
return 1;
}
//echo”sess_destroy key=$key
$query=mysql_query(“DELETE FROM sugar_session4 WHERE sess_key=’$key'”) or die(mysql_error());
}
//echo”sess_gc lifetim=$lifetime
“;
mysql_query(“DELETE FROM sugar_session4 WHERE last_log<".time()) or die(mysql_error());
return true;
}
###################login.php###############
include”sess_test.php”;
echo(“
“);
{
echo(“
}
else
{
echo(“
}//else end
{
$conv_passwd=mysql_result($sql,0,0);
$e_check=mysql_num_rows($sql);
$row=mysql_fetch_array($sql);
if($e_check==”)
{
echo(“
“);
}
else
{
$sess_id=”$row[id]”;
session_register(sess_id);
//echo”로그인 에서 의 HTTP_SESSION_VARS[sess_id] = $HTTP_SESSION_VARS[sess_id]
“;
}
########logout.php#########
include”sess_test.php”;
session_destroy();
?>세션을 DB로 관리하기 + 쪽지 확인하기
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_start();
return 1;
}
$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];
}
$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 ”;
}
return 1;
}
$DB =& DB::getInstance();
$DB->query(“UPDATE user_sessions SET sess_key=”, last_log='”.time().”‘, last_ip='”.$_SERVER[“REMOTE_ADDR”].”‘ WHERE sess_key=’$key’ “);
}
return 1;
}
비회원인 경우는 session_start()를 하더라도 세션키값만 주어질 뿐, 여러가지 $_SESSION값을 사용할 수 없습니다. (물론 쿠키값을 이용해 비회원의 경우는 아예 session_start()를 실행하지 않는 방법도 있죠. ^^;;)
자, 이쯤에서 한가지 욕심을 내어볼까요? 이른바, 쪽지 기능을 추가해보겠습니다. (실시간 쪽지 기능 아닙니다. –;;)
제로보드인가? 쪽지를 받으면 “딩동, 새로운 메시지가 도착했습니다” 하는 소리가 나쟎아요.
받은 쪽지 테이블을 따로 만들면, 매번 해당 테이블을 읽어야 하지 않습니까. 뭐 굳이 2번 작업을 하냐, 세션을 시작하면서 자동적으로 그 데이타를 읽어오자 하는거지요.
ALTER TABLE `user_sessions` ADD `chk_msg` TINYINT(2) UNSIGNED NOT NULL AFTER `last_ip` ;
다른 회원이 쪽지를 보낼때, chk_msg 값을 하나씩 증가시키고, 쪽지를 확인하면 chk_msg 값을 0로 update하려는 것입니다.
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와 같은 변수를 할당하지 않고, $_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를 만들자”는 취지에서 한번 써봤고, 나름대로 효율적이라고 생각하는데… 장담은 못하겠네요. 오류나 정정사항은 리플 부탁드립니다.한솔교육 판촉장비 지원시스템


외부에 직접 노출되지 않고 한솔교육의 교사용웹에 로그인하여 이동할 수 있다.
특이사항은 배송장 부분. 일별 또는 지정일별로 각 지점주소를 기준으로 같은 지점소속
직원이 주문한 상품을 동일한 박스에 담을 수 있도록 배송장 출력됨.
배송장 부분때문에 카트부분부터 DB까지 모두 수정.
일괄주문 페이지 : 각 조직의 총무가 각 교사의 신청을 대행하도록 일괄주문 페이지 제작.요즘 수박의 머릿속엔…
아이고 머리야….
언제쯤 프로그램 실무에서 손을 떼게될까?
수정하는거야 그리 큰 에너지가 안드는데 새로 작성하는 것은
무지 많은 에너지를 소비… 이젠 머리도 잘 안돌아가고… 흑흑
로직이 생각이 잘 안나… 어떡하지..
머리야~~