CI 묻고 답하기

제목 검색 파라미터 질문입니다.
글쓴이 마냐 작성시각 2009/07/12 15:32:26
댓글 : 5 추천 : 0 스크랩 : 0 조회수 : 31615   RSS
안녕하세요?
 
파라미터 값을 받을 때 ... /page/1/sfl/subject/stx/test
... /변수/값/변수/값/변수/값 이런형식으로 받으시던데 어떻게 구현하시는지 궁금합니다. 참조 링크라도...
 
CI에서 지원하는 식으로 function 인자로 처리할려고 하니 인자가 늘어날 수록 복잡해 지더군요. ㅡ_
Pagination도 꼬이고...
 
 다음글 [질문] table library 에서 컬럼<td... (7)
 이전글 [질문] url에서 마지막에 나오는 / 를 제거하는 방... (3)

댓글

우노 / 2009/07/12 16:07:32 / 추천 0
저도 지금 같은 고민을 하고 있습니다.
wiki 를 생각하다보니 segment 가 정해진 순서가 아니어서, 인자를 넘기는 방법을 생각해 보고 있습니다.

wiki/aaa/bbb/ccc/ddd::var1:param1::var2:param2 의 형태라면 wiki 에서 쓰는데 문제가 없지 않을까 생각해봅니다.

< 예 pagename -> aaa/bbb/ccc/ddd, ::action:delete::version:32 -> ?action=delete&version:32 과 같은 형태이죠...>
다만, 해석하는 정규식을 어떻게 짜나 시작도 안하고 고민하고 있었습니다. Pagination 의 경우는 아직 깊게 생각안해봤지만 :: 이후로는 날려버리면 되지 않을까요?

_remap() 을 기준으로 생각해 봤는데, 일반적인 경우에도 적용이 가능할 수도 있지 않을까요?
변종원(웅파) / 2009/07/12 21:11:35 / 추천 0
개발할때 몇번째 세크먼트까지는 항상 디폴트로 쓴다고 정하면
예를 들어 지금 개발중인 cms는 /product/tv/list/page/1 /대분류/중분류/메소드/페이징변수/페이징변수값 이렇게 사용하고 그 이후에는
무조건 변수명/변수값 쌍으로 사용을 합니다. 아직 주소 전체를 배열 쌍으로 만드는 프로그램을 사용하지는 않고 원하는 세그먼트의
값을 가져오는 함수(울 양대리님 작품)를 하나 만들어서 사용중입니다.

먼저 주소를 배열로 만들고 (우노님 아랫 질문의 답도 됩니다)

function segment_explode($seg) { //세크먼트 앞뒤 '/' 제거후 uri를 배열로 반환
$len = strlen($seg);
if(substr($seg, 0, 1) == '/') {
$seg = substr($seg, 1, $len);
}
$len = strlen($seg);
if(substr($seg, -1) == '/') {
$seg = substr($seg, 0, $len-1);
}
$seg_exp = explode("/", $seg);
return $seg_exp;
}

function url_explode($url,$key){
for($i=0; count($url)>$i; $i++ ){
if($url[$i] ==$key){
$k = $i+1;
return $url[$k];
}
}
}

$this->seg_exp = $this->segment_explode($this->uri->uri_string());
$this->data['skin'] = $this->url_explode($this->seg_exp,"skin");

위 두 함수를 조합하면 한번에 원하는 변수의 값을 가져올 수 있겠죠.

그리고 마냐님이 질문하신 /page/1/sfl/subject/stx/test 형식은

$arr_key = array_keys($this->seg_exp, "q");
$arr_val = $arr_key[0] + 1;
$search_word = $this->seg_exp[$arr_val];
$arr_key1 = array_keys($this->seg_exp, "sfl");
$arr_val1 = $arr_key1[0] + 1;
$sfl = $this->seg_exp[$arr_val1];
$post = array('method'=>$sfl, 's_word'=>$search_word);
이렇게 사용중인데 위의 역할을 함수로 만들어놓은게 url_explode 함수입니다.
변종원(웅파) / 2009/07/12 21:56:44 / 추천 0
/product/tv/list/page/1/ 의 경우 내부에 _remap() 역할을 하는 함수가 하나 있습니다.

현재 개발중인 cms의 기본 구조가 matchbox(application 디렉토리 외부에 application과 동일한 구조를 갖게 하고 ci주소로 접근가능하게 하는 라이브러리. ) + widget 입니다. 거기에 파싱 라이브러리 하나 만들고 자체적으로 주소체계 처리하는 부분이 들어있습니다.

위 주소의 경우 첫번째와 두번째는 메뉴관리에서의 대분류 중분류에 해당합니다. product 카테고리중에 tv라는 상품이고 속성으로 게시판이 연결되어있습니다.
그래서 lists라는 메소드가 연결되어 해석하고 첫번째 페이지를 보여주는 구조입니다.
게시판이 연결되지 않고 html 페이지가 연결되어 있다면 주소는 /product/tv/로 끝납니다. 내부에서 html페이지로 연결해주고 끝.

cms에서 위의 주소체계는 DB의 메뉴형태를 기준으로 자동으로 만들어지고, 그 주소를 해석해서 프로그램으로 연결하는 형태로 되어있습니다.

접근하는 방식에 있어서 주소형태를 먼저 확정하고 그에 따라 db구조를 만들거나 db구조에 따라 주소를 만들어주는 형태가 있을 수 있겠죠.
제가 wiki는 자세히 들여다보지 않아서 정확한 구조는 모르겠지만 aaa/bbb/ccc 가 디렉토리 구조 또는 메뉴 구조 또는 작성자를 나타내는 것이라면
테이블을 하나 더 만들고 그 테이블의 번호를 사용하여 주소를 간편화시키는 것도 하나의 방법이 될 수 있겠습니다.

일반 게시판과 같은 구조라면 /게시판db tble명/메소드/번호/페이징/페이지번호 형태가 기본이 될테구요. 메소드에 따라 세번째 세그먼트인 번호는 있을수도 있고
없을 수도 있고. 그건 프로그램에서 처리를 하면 될것이구요.

위에 말씀하신 /action:delete::version:32 형태는 앞의 세그먼트 갯수가 항상 고정적일때는 사용하기 편한데 계속 바뀐다면 값을 가져오기가 애매할 수도 있습니다.
(검색후 페이징시)
변종원(웅파) / 2009/07/12 22:02:05 / 추천 0
아직 개발 완료된 소스는 아니지만 마냐님이 올리신 주소에 해당하는 클래스와 메소드입니다.
주소를 처리해서 어떻게 모델에 넘기고 페이징에 적용하는지 참고가 되실 겁니다.

http://localhost/file/lists/page/1/q/글/sfl/subject

class Board extends Controller {

function Board()
{
parent::Controller();

$rew = $this->db->get_where('board_list', array('name_en'=>'board_'.$this->uri->segment(1)));
$item = $rew->row();
define('MENU_ID', $item->no);
define('MENU_SKIN', $item->skin);
define('MENU_BOARD_NAME', $item->name);
define('MENU_BOARD_NAME_EN', $item->name_en);
define('MENU_BOARD_PERM', $item->permission);
define('MENU_BOARD_DETAIL_SETTING', $item->detail_setting);

$this->load->model('board_model');

$perm = explode("|", MENU_BOARD_PERM); //목록보기,게시물보기,댓글작성,게시물쓰기
$this->list_perm = $perm[0];
$this->view_perm = $perm[1];
$this->reply_perm = $perm[2];
$this->write_perm = $perm[3];

$this->output->enable_profiler(false);
$this->seg_exp = $this->common->segment_explode($this->uri->uri_string());
}

function index() {
switch($this->uri->segment(2)) {
case 'lists':
$this->lists();
break;
case 'view':
$this->view();
break;
case 'write':
$this->write();
break;
}
}

function lists() //$plugin, $function, $skin
{
if(in_array("q", $this->seg_exp)) {
$arr_key = array_keys($this->seg_exp, "q");
$arr_val = $arr_key[0] + 1;
$search_word = $this->seg_exp[$arr_val];
$arr_key1 = array_keys($this->seg_exp, "sfl");
$arr_val1 = $arr_key1[0] + 1;
$sfl = $this->seg_exp[$arr_val1];
$post = array('method'=>$sfl, 's_word'=>$search_word);
} else {
$post = '';
}
if(($this->session->userdata('auth_code') == 'ADMIN' ) or ($this->session->userdata('auth_code') >= $this->list_perm) or ($this->list_perm == 1) ) {
$data['list_total'] = $total = $this->board_model->load_list_total($post);
//페이징
if(in_array("page", $this->seg_exp)) {
$arr_key = array_keys($this->seg_exp, "page");
$arr_val = $arr_key[0] + 1;
$data['page_account']=$page = $this->seg_exp[$arr_val];
} else {
$data['page_account']=$page = 1;
}

$rp = 20; //리스트 갯수
$limit = 9; //보여줄 페이지수

$start = (($page-1) * $rp);

//검색후 페이징처리위한..
//print_r($this->seg_exp);
$this->url_seg = $this->seg_exp;
$arr_s = array_search('page', $this->url_seg);
array_splice($this->url_seg, $arr_s, 2);

$urls = implode('/', $this->url_seg);

$data['pagination_links'] = $this->common->pagination($urls."/page", paging($page,$rp,$total,$limit));

$data['list'] = $this->board_model->load_list($start, $rp, $post, MENU_BOARD_NAME_EN);

$this->load->view('top_v');
$this->load->view('board/'.MENU_SKIN.'/lists', $data);
$this->load->view('bottom_v');
} else {
echo "권한이 없습니다. 로그인이 필요한 페이지입니다. 로그인";
}

}
}
마냐 / 2009/07/13 16:03:46 / 추천 0
감사합니다. 웅파님 말씀을 토대로 잘 해결 하였습니다. '~'/