제목 | ci 답변형 게시판입니다. | ||
---|---|---|---|
글쓴이 | 개발사랑 | 작성시각 | 2013/02/06 14:14:42 |
|
|||
제가 이해한 로직이 맞는지도 점검할겸 글을 올립니다. 잘못되었으면 말씀해주세요. 일전에 다른분이 올려주신 소스에 답글과 spac_editor 등을 추가했습니다. 아 코드이그나이터를 이용해서 만들었습니다. 액티브레코드도 부분 부분 사용했습니다. 먼저 4가지의 필드가 필요합니다. no = int로서 순차적으로 증가되는 각 필드의 고유값 list_number = 실제 정렬된 순서를 지정하는 필드 depth = 답글의 깊이를 정함 parent = 원본글의 no 값(저도 다른곳의 포스트를 보고 만들었는데 실제로서는 이 필드는 거의 필요가 없는듯 합니다.) 일단 리스트 출력상에서는 list_number asc로 출력합니다. 새글 기입시 등록된 글이 없이 처음일시 list_number에 무조건 1을 기입하도록 합니다. 새글등록시 이미 등록된 글에 가장 최신 list_number에 -1을 해 list_number를 등록하게 되어 있습니다. 이때 로직상 -1 이거나 0으로 되면 1로 세팅해서 업데이트 시킵니다. 그 이외에는 새 글 기입시 등록된 글보다 no값이 작은 경우 무조건 list_number를 +1시키고 새글은 등록된 글 중 가장 작은 list_number 값을 추출해 그 값에 -1을 해 입력시킵니다. 이때 parent_id는 원본글의 값 depth는 1로 세팅합니다. 답변글 등록시 parent_id는 원본글의 값 depth는 원본글의 depth에서 +1를 해 처리합니다. list_number는 원본글의 list_number보다 큰 경우 전부 +1을 해주고 새글의 list_number는 원본글의 list_number에서 +1을 해 처리합니다. 그러면 원본글의 list_number보다 큰 경우와 원본글 사이에 숫자가 하나남는 상황이 생기고 그 숫자로 답글이 처리되어 list_number asc를 하면 답글이 원본글의 바로 밑에 출력됩니다. 아래는 소스입니다. 저도 정리한다고 남기는글인데 두서 없네요 혹시 의문사항이 생기시면 답글 바랍니다. 새글 기입시 (주석참고) $this->title = $_POST['title']; $this->memo = $_POST['memo']; $this->name = $_POST['name']; $this->img01 = $_FILES['userfile']['name']; $this->ip = $_SERVER["REMOTE_ADDR"]; $this->date = date("Y-m-d H:i:s",time()); /* $this->db->select_max('thread'); $result_set = $this->db->get('board'); $thread_array = $result_set->result_array(); print_r($thread_array); exit; */ $this->db->insert('board', $this); // 핵심은 list_number 필드에 있다. // 그런데 데이터 많으면 부하걸리겠다. list_number를 계속 업데이트 해주어야 한다. // 삽입된 원글의 아이디값을 추출한다. $id = $this->db->insert_id(); // 원글보다 먼저 등록된 글들의 list_number를 다 1씩 증가시킨다. // 왜냐하면 답글이 아니고 신규글이기 때문에 제일 위에 정렬된다. $this->db->query("update board set list_number=list_number+1 where no <".$id); // 가장작은 리스트 넘버의 값을 추출해서 거기에 -1를 한 값이 최종글의 번호가 된다. // 게시판 리스트 정렬시에는 가장 작은 값이 위에 오게된다. $res = $this->db->query("select min(list_number) as list_number_min from board"); $board_array = $res->result_array(); $num_rows = $res->num_rows(); $set_list_number = $board_array[0]['list_number_min'] - 1; if($set_list_number == -1 || $set_list_number == 0) { $set_list_number = 1; } $data = array( 'list_number' => $set_list_number, 'depth' => 1, 'parent' => $id ); $this->db->where('no', $id); $this->db->update('board', $data); 답글 기입시(주석참고) $this->title = $_POST['title']; $this->memo = $_POST['memo']; $this->name = $_POST['name']; $this->img01 = $_FILES['userfile']['name']; $this->ip = $_SERVER["REMOTE_ADDR"]; $this->date = date("Y-m-d H:i:s",time()); /* $this->db->select_max('thread'); $result_set = $this->db->get('board'); $thread_array = $result_set->result_array(); print_r($thread_array); exit; */ $this->db->insert('board', $this); $id = $this->db->insert_id(); // 답글의 원본글의 정보를 추출한다. $this->db->select('*'); $this->db->from('board'); $this->db->where('no', $_POST['no']); $query = $this->db->get(); $sel_board_array = $query->result(); $depth = $sel_board_array[0]->depth + 1; // 원본글의 list_number보다 큰 먼저 정렬된글들의 list_number를 전부더해 답글의 밑에 보이도록 한다. // 이때 list_number가 작은글들은 업데이트 되지 않는다 왜냐하면 list_number가 큰 글들을 전부 +1 업데이트 시키고 // 원본글과 +1 시킨 글 사이에 답글의 list_number가 위치할것이기 때문이다. $this->db->query("update board set list_number=list_number+1 where list_number >".$sel_board_array[0]->list_number); $set_list_number = $sel_board_array[0]->list_number + 1; if($set_list_number == -1 || $set_list_number == 0) { $set_list_number = 1; } $data = array( 'list_number' => $set_list_number, 'depth' => $depth, 'parent' => $sel_board_array[0]->no ); $this->db->where('no', $id); $this->db->update('board', $data); // $res_set = $sel_board_array[0]->res + 1; // $rev_set = $sel_board_array[0]->rev + 1; // $this->db->set('res', 'res+1'); // $this->db->where('ref', $_POST['ref']); // $this->db->where('res >', $sel_board_array[0]->res); // $this->db->update('board'); // $this->db->query("update board set res=res+1 where ref ='".$_POST['ref']."' and res > ".$sel_board_array[0]->res); // $this->db->query("update board set ref=".$_POST['no'].", rev = ".$rev_set.", res=".$res_set." where no = ".$id); // $this->db->query(); /* $data = array( 'ref' => $_POST['no'], 'res' => $res_set, 'rev' => $rev_set ); $this->db->where('ref', $id); $this->db->where('res >', $sel_board_array[0]->res); $this->db->update('board', $data); */ |
|||
첨부파일 |
board.zip (8.6 KB) |
||
다음글 | ci 1.7 -> ci 2.1.3 업그레이드 방법 (3) | ||
이전글 | HMVC 사용시 Form_validation callb... (1) | ||
변종원(웅파)
/
2013/02/06 14:44:10 /
추천
0
|
개발사랑
/
2013/02/06 16:21:20 /
추천
0
예를 들면 어떤 로직이 있을까요? 좋은 곳 있으면 포스트 부탁드립니다. |
변종원(웅파)
/
2013/02/06 17:17:13 /
추천
0
네이버나 phpschool에서 검색해보시면 로직들 좀 나옵니다.
필드는 거의 비슷합니다. 3개의 필드로 되어있고 업데이트형이냐 비업데이트형이냐로 나뉘구요. 소수점 방식도 있고... 시간이 되면 전에 만든 게시판 로직 올려보겠습니다. |
개발사랑
/
2013/02/06 17:47:57 /
추천
0
네 감사합니다. 꼭 좀 부탁드립니다! |
변종원(웅파)
/
2013/02/07 13:03:13 /
추천
0
board table id auto increment board_pid 게시판 원글, 답글 번호 reply_order 답글의 정렬용. 원글일 경우 0 is_delete 삭제여부 필드 Y 이면 삭제된 글임 is_list 삭제는 됐지만 리스트에 보여줄 필요가 있는 경우(원글이 삭제된 답글입니다. 구현용) Y이면 is_delete가 Y이더라도 리스트에 보여준다. 완전히 안보이는 경우는 is_delete='Y' and id_list='N'인 경우임. 1. 입력시 board_pid는 원글일 경우 기존 max값+1 하여 입력, 답글일 경우는 원글의 board_pid입력 reply_order는 원글일 경우 0, 답글일 경우는 기존 reply_order+1 2. 리스트 select 시의 주요 항목 where (is_delete='N' and .is_list = 'Y') or (is_delete='Y' and is_list = 'Y') order by board_pid desc, reply_order asc, id desc board_comments id auto increment comment_id 원 게시글의 번호 board_id 원 게시글의 번호 comment_order AAA형태 (알파벳 3개 기본, 3개씩 추가) 1. 입력시 comment_id와 comment_order 구하는 방식 $this->db->select_max('comment_id'); $this->db->select_max('comment_order'); $this->db->where('length(comment_order)', 3); $this->db->where('board_id', $post['no']); $query = $this->db->get($this->comment_table); @$comment_nos = $query->row() ; $comment_id = @$comment_nos->comment_id + 1 ; $comment_order = @$comment_nos->comment_order; if($comment_order == '') { $comment_order_no = 'AAA'; } else { $comment_order_no = $this->depth_check2($comment_order,''); } 2. 댓글 리스트 comment_id desc, LENGTH(comment_order) asc 참고함수 : AAA 에서 AAB로 올려주는 역할, AAZ에서 +1하면 ABA로. depth는 AAA는 1depth, AAAAAA일 경우 2depth function depth_check2($depth, $type) { if($type == 'level') { $now_article = $depth."AAA"; } else { $length = strlen($depth); $cot = $length / 3; if($cot > 0) { $odepth = substr($depth, 0, $length-3); $depth = substr($depth, $length-3, 3); $length = strlen($depth); } $pre = substr($depth,0,1); $mid = substr($depth,1,1); $last = substr($depth, $length-1,1); $temp1 = ord($pre); //문자를 숫자로 $temp2 = ord($mid); //문자를 숫자로 $temp3 = ord($last); //문자를 숫자로 if($temp3 >= 90) { //Z 이하이면 $temp3 = "65"; $temp2 ++; if($temp2 >= 90) { $temp2 = "65"; $temp1 ++; if($temp1 >= 90) { $temp1 = "90"; } } } else { $temp3 ++; } if($cot > 0) { $now_article = $odepth.chr($temp1).chr($temp2).chr($temp3); //증가시킨 값을 넣기 } else { $now_article = chr($temp1).chr($temp2).chr($temp3); //증가시킨 값을 넣기 } } return $now_article; |
변종원(웅파)
/
2013/02/07 13:08:38 /
추천
0
개발사랑/
게시판 리스트의 답글은 무한depth는 아니고 1depth만 구현이 됐네요. (댓글 로직 적용하면 무한 가능) 대신 원글을 삭제했을 경우 원글이 삭제됐습니다 라고 표기하고 답글을 아래에 표현할 수 있게 처리했습니다. (네이버 카페 처럼) 로직 보니 댓글 무한 depth이긴 하나 AAA 형태로 AAAAAAAAAAAAA...... 무한대로 길어질 수 없는터라 실제적으로는 long text 필드 길이만큼 구현이 가능합니다. 보기가 좀 어려울 수 있는데 보시고 궁금한 사항은 올려주세요. |
개발사랑
/
2013/02/07 13:57:00 /
추천
0
네 감사합니다! 잘 볼게요! 답글도 무한 depth인거는 올려주실 수 없을런지요!?ㅋ 말씀을 들어보니 게시판 답글이 무한이 아니라고 하신거 같아 문의합니다 맞나요?ㅋ |
변종원(웅파)
/
2013/02/07 14:06:12 /
추천
0
개발사랑/ depth 필드만 넣으면 될건데요? ^^
|
꾸숑
/
2013/02/07 15:08:47 /
추천
0
개발사랑// 저 같은 경우에는 딱 코드 5줄?로 답글을 구현했습니다.
CI를 사용하니 코드 길이가 확 줄어 드네요... http://www.codeigniter-kr.org/source/view/665/page/1/ 이곳 자료를 보면 application/views/write_form_view.php $query = $this->db->query("select MAX(gnum) as gnum from 테이블명"); $gnum = current( $query->row_array()); $gnum += 1; application/views/comment_form_view.php $query = $this->db->query("select MAX(depth) as depth from 테이블명 where depth like '$depth%' and gnum=$gnum"); $depth = $depth.chr(ord(substr($depth, -1)) +1); application/models/board_model.php //24줄 $this->db->order_by('gnum desc, depth asc'); 이렇게 되어 있습니다. 제가 길게 설명할 실력은 않되지만 참고하세요 제대로 작동 됩니다. |
개발사랑
/
2013/02/08 09:02:14 /
추천
0
네 감사합니다!
|
개발사랑
/
2013/02/08 15:04:56 /
추천
0
구현중 모르는 부분이 생겨 글 드립니다. 답변 부탁드립니다. ㅠㅠ
comment_id desc 하면 나중에 작성한 답글이 무조건 위로 올라가지 않나요? 그리고 이미 고유의 id가 자동증가되게 되어 있는데 comment_id가 의미가 있나요? |
변종원(웅파)
/
2013/02/08 15:25:26 /
추천
0
개발사랑/ 네 id는 사실 중복입니다
|
개발사랑
/
2013/02/08 15:49:16 /
추천
0
다시 의문이 생겨 글 드립니다 ㅠㅠ 답변 감사드립니다. |
변종원(웅파)
/
2013/02/08 16:04:38 /
추천
0
개발사랑/ 아래 함수에 $type에 level을 주면 레벨업(depth 업)이 됩니다.
function depth_check2($depth, $type) { if($type == 'level') { $now_article = $depth."AAA"; } |
개발사랑
/
2013/02/08 16:06:21 /
추천
0
다시 의문이 생겨 글 드립니다. ㅠㅠ
id 값으로 desc를 하면 답글이라도 무조건 최상위로 올라가는데요 이 부분 어떻게 처리해야 할지요? |
주석에 보니 list_number 를 계속 업데이트 하는데 주석에 쓰신 것처럼
데이터가 많이지면 느려질 수 밖에 없습니다.
업데이트 하지 않는 로직들도 있으니 그걸 적용해서 만드시는게 좋을 것 같습니다.
로직은 머리 아프긴 합니다. 전에 게시판 답글 무한depth, 덧글 무한depth 구현하느라
머리 아팠던 기억이 나네요.