본문 바로가기

old

CI(Codeigniter)의 세션변수 user_data가 공란인 이유

CI에서 세션에 데이터를 등록하려면 다음과 같다.

$var = array('data1'=>'bla','data2'=>'blabla', ...);

$this->load->library('session');

$this->session->set_userdata($var);


세션에 등록한 데이터를 갖다 쓰려면 다음과 같다.

$this->load->library('session');


// 1번 방법

$var_1 = $this->session->userdata('data1');

$var_2 = $this->session->userdata('data2');


// 2번 방법

$var = $this->session->all_userdata();


1번 방법으로 하기엔 뭔가 스마트하지가 않고... 그래서 2번 방법으로 하려고 보니 뭔가 쓰잘데기 없는 데이터가 붙어서 온다. (사실 쓰잘데기 없는 것은 아니지만ㅋㅋ 내가 원하는 데이터는 아니다.)

// 2번 방법으로 ( all_userdata() ) 데이터를 가져온 경우 반환값이 다음과 같다.

array(

[session_id] => .....,

[ip_address] => .....,

[user_agent] => .....,

[last_activity] => .....,

[user_data] => ,

[data1] => bla,

[data2] => blabla

);


난 당연히 all_userdata()의 반환값이 이렇게 나올 줄 알았다.

array(

[data1] => bla,

[data2] => blabla

);


가이드문서는 아무리 봐도 뭐가 잘못됐는지를 모르겠어서 CI의 코드를 살펴봤다.

( system/libraries/Session.php, function __construct() 中 )

...

if(!$this->sess_read())

{

$this->sess_create();

}

...


CI_Session 클래스의 생성자를 보면, 세션이 없다면 (if(!$this->sess_read()) 새로 생성한다 ($this->sess_create())고 나와있고... 그렇다면 sess_create()를 살펴보자.

( system/libraries/Session.php, function sess_create() 中 )

...

$this->userdata = array(

'session_id' => md5(uniqid($sessid, TRUE)),

'ip_address' => $this->CI->input->ip_address(),

'user_agent' => substr($this->CI->input->user_agent(), 0, 120),

'last_activity' => $this->now,

'user_data' => ''

);

...


범인을 찾았다. 그럼 여기서 의문점이 나온다. 세션을 등록할때 사용하는 set_userdata() 함수를 이용하면 저기 빈칸으로 남겨지는 'user_data'에 등록되는게 아닌가? 코드를 보자.

( system/libraries/Session.php, function set_userdata() )

function set_userdata($newdata = array(), $newval = '')

{

if (is_string($newdata))

{

$newdata = array($newdata => $newval);

}


if (count($newdata) > 0)

{

foreach ($newdata as $key => $val)

{

$this->userdata[$key] = $val;

}

}


$this->sess_write();

}


결국 set_userdata($arr)의 기능은 $arr의 각 요소를 $this->userdata 배열변수에 새로운 요소로 추가시키는 작동만 할 뿐, 매개변수 $arr이 $this->userdata['user_data']로 들어가지는 않는다. 그렇다면 sess_create()에서는 왜 'user_data'요소를 만드는건가?

( system/libraries/Session.php, function sess_read() 中 )

...

// Is there custom data?  If so, add it to the main session array

$row = $query->row();

if (isset($row->user_data) AND $row->user_data != '')

{

$custom_data = $this->_unserialize($row->user_data);

if (is_array($custom_data))

{

foreach ($custom_data as $key => $val)

{

$session[$key] = $val;

}

}

}

...


session을 쿠키가 아닌 DB로 관리할 때 사용되는거였다... 난 쿠키로 사용할 것이므로 이 부분을 무시하려면 어떻게 해야될까. 간단하다. set_userdata()에 매개변수로 넣는 배열을 2차 배열로 넣으면 된다.

$var = array('data1'=>'bla','data2'=>'blabla', ...);

$this->load->library('session');


// 원래는 아래와 같이 그냥 배열을 직접 넣었지만

$this->session->set_userdata($var);


// 이렇게 넣으면 $this->userdata['user_data']로 들어간다.

$this->session->set_userdata(array('user_data' => $var));


이렇게 하면 이제 all_userdata()의 반환값은 아래와 같이 바뀐다.

array(

[session_id] => .....,

[ip_address] => .....,

[user_agent] => .....,

[last_activity] => .....,

[user_data] => array(

[data1] => bla,

[data2] => blabla

)

);


사실 system 코드를 수정해서 session_id, ip_address, user_agent, last_activity 요소들까지 지워버릴까 했지만, 코어를 건드려버리면 나중에 뒤처리가 골치아플 것 같아서... 게다가 여기저기 필요한 페이지가 많을 것 같아서 그냥 두기로 했다.