일반적인것과 그룹화 한 것 두가지 샘플이 있으니 보시면 아실거 같고
리팩토링은 알아서 하시길 바랍니다.
버그있음 댓글달아주세요 (그룹화 해본적이 없어 이런상으로 계산된거라 제대로 나오는지는 모르겠습니다.)
본 코드는 아무렇게가 갖다 쓰심 됩니다.
<?php
// vim600: ts=4 sw=4
class C
{
// constants
const ERR_PAGING_ROW = 10001;
const ERR_PAGING_SCALE = 10002;
const ERR_PAGING_PART_INFO_INVALID = 10003;
const ERR_PAGING_PART_NO_NOT_INTEGER = 10004;
const ERR_PAGING_PART_COUNT_NOT_INTEGER = 10005;
// only static
private function __construct () {}
/**
@param array
int total : 전체 게시물수
int page : 현제 페이지번호
int row : 페이지당 게시물 수
int scale : 페이징 블럭 (페이지에 보여질 번호판 수)
string link : page=xxx 를 지외한 모든 링크
예) aaa.php?a=$a&b=$b&c=$c&page=$page 이런 링크가 필요하다면
link = "a=$a&b=$b&c=$c";
array group : 분할정보 (division 정보) 미사용시 필요없음
int no => int count
@param part : boolean - 데이타를 group(division) 화 하는지의 여부
@return array
total : 전체 게시물 수
page : 현제 페이지 번호
totalpage : 총 페이지 수
prev_link : 이전 링크
paging : 번호판 리스트
next_link : 다음 링크
start_link : 처음 링크
end_link : 마지막 링크
enable_prev : 이전페이지 가능한가?
enable_next : 다음페이지 가능한가?
object query : group 화 정보 (쿼리용 변수)
int limit : 쿼리에서 사용할 limit
int offset : 쿼리에서 사용할 offset
array group : 쿼리에서 사용할 group number list
*/
public static function paging (array $arr, $part = false)
{
$total = intval($arr['total']);
$page = intval($arr['page']);
$row = intval($arr['row']);
$scale = intval($arr['scale']);
$link = $arr['link'];
$group = $arr['group'];
if($link) $amp = '&';
if($row < 1)
throw new Exception (self::ERR_PAGING_ROW);
if($scale < 1)
throw new Exception (self::ERR_PAGING_SCALE);
if($page < 1) $page = 1;
$totalpage = ceil($total / $row);
if($page > $totalpage) $page = $totalpage;
if($total > 0) {
$start = (intval($page / $scale) * $scale) + 1;
if(!($page % $scale)) $start -= $scale;
$end = $start + $scale - 1;
if($end > $totalpage) $end = $totalpage;
$prev = $start - $scale;
$next = $start + $scale;
}
for($i = $start; $i <= $end; $i++)
$paging_loop[] = array('page_num' => $i,
'page_link' => "page=".$i.$amp.$link);
$count = count($paging_loop);
if($count > 0) $paging_loop[$count-1]['end'] = 1;
$limit = $row;
$offset = ($page - 1) * $row;
if(!$part) {
$_grp->limit = $limit;
$_grp->offset = $offset;
}
else {
if(!is_array($group))
throw new Exception(self::ERR_PAGING_PART_INFO_INVALID);
try {$_grp = self::_make_query_info($group, $limit, $offset); }
catch (Exception $e) { throw $e; }
}
$arr = array('total' => $total,
'page' => $page,
'totalpage' => $totalpage,
'prev_link' => 'page='.$prev.$amp.$link,
'paging' => $paging_loop,
'next_link' => 'page='.$next.$amp.$link,
'start_link' => 'page=1'.$amp.$link,
'end_link' => 'page='.$totalpage.$amp.$link,
'enable_prev' => ($page > $scale) ? true : false,
'enable_next' => ($end < $totalpage) ? true : false,
'query' => $_grp
);
return $arr;
}
private static function _make_query_info(array $grp, $limit, $offset)
{
$start = $offset;
$end = $offset + $limit;
$sum = 0;
$found = false;
$pos = array();
$_offset = 0;
foreach($grp as $part => $count) {
if(!is_int($part) || $part < 1)
throw new Exception(self::ERR_PAGING_PART_NO_NOT_INTEGER);
if(!is_int($count))
throw new Exception(self::ERR_PAGING_PART_COUNT_NOT_INTEGER);
$sum += $count;
if($sum > $start) $found = true;
if($found) {
$pos[] = $part;
if(!$_offset) $_offset = $offset + $count - $sum;
}
if($sum >= $end) break;
}
if(!is_array($pos))
throw new Exception(self::ERR_PAGING_PART_INFO_INVALID);
$group->group = $pos;
$group->offset = $_offset;
$group->limit = $limit;
return $group;
}
public static function get_errmsg ($const)
{
switch($const) {
case self::ERR_PAGING_ROW:
return '페이지당 출력수를 셋팅해 주세요';
case self::ERR_PAGING_SCALE:
return '페이징 블럭을 셋팅해 주세요';
case self::ERR_PAGING_PART_INFO_INVALID:
return '분할정보가 없거나 잘못되었습니다.';
case self::ERR_PAGING_PART_NO_NOT_INTEGER:
return '분할번호가 숫자가 아니거나 없습니다.';
case self::ERR_PAGING_PART_COUNT_NOT_INTEGER:
return '해당분할그룹의 정보가 숫자가 아닙니다.';
default: return '알수 없는 에러입니다.';
}
}
}
// example1 - 그룹화 하지 않은 경우
$arr = array('total' => 5,
'page' => 1,
'row' => 10,
'scale' => 10);
try {$paging = C::paging($arr); }
catch (Exception $e) {
print 'LINE: '.$e->getLine().' '
.C::get_errmsg($e->getmessage());
exit;
}
// pgsql 에서는 limit offset 이 limit $limit offset $offset
// mysql 에서는 limit $offset,$limit
// oracle 에서는 RN between ($offset + 1) and ($offset + $limit)
// 또는 각자 알아서 영역을 구하시길
$query = "select xxxxx from xxxx order by xxx "
."limit ".$paging['query']->limit." offset ".$paging['query']->offset;
$tpl->assign($paging);
// example2 - 그룹화 할 경우 (division 사용시)
// 앞은 분할번호 뒤는 갯수
// 최신정보부터 뒤집어 넣습니다.
$division = array(5 => 205,
4 => 5000,
3 => 5029,
2 => 4800
);
$arr = array('total' => 15034,
'page' => 22,
'row' => 10,
'scale' => 10,
'group' => $division);
try {$paging = C::paging($arr, true); }
catch (Exception $e) {
print 'LINE: '.$e->getLine().' '
.C::get_errmsg($e->getmessage());
exit;
}
$query = "select xxxxx from xxxx "
."where xxxx "
."and division in (".implode(',', $paging['query']->group).") "
."order by xxx "
."limit ".$paging['query']->limit." offset ".$paging['query']->offset;
$tpl->assign($paging);
?>
펌:http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=57690&page=1
리팩토링은 알아서 하시길 바랍니다.
버그있음 댓글달아주세요 (그룹화 해본적이 없어 이런상으로 계산된거라 제대로 나오는지는 모르겠습니다.)
본 코드는 아무렇게가 갖다 쓰심 됩니다.
<?php
// vim600: ts=4 sw=4
class C
{
// constants
const ERR_PAGING_ROW = 10001;
const ERR_PAGING_SCALE = 10002;
const ERR_PAGING_PART_INFO_INVALID = 10003;
const ERR_PAGING_PART_NO_NOT_INTEGER = 10004;
const ERR_PAGING_PART_COUNT_NOT_INTEGER = 10005;
// only static
private function __construct () {}
/**
@param array
int total : 전체 게시물수
int page : 현제 페이지번호
int row : 페이지당 게시물 수
int scale : 페이징 블럭 (페이지에 보여질 번호판 수)
string link : page=xxx 를 지외한 모든 링크
예) aaa.php?a=$a&b=$b&c=$c&page=$page 이런 링크가 필요하다면
link = "a=$a&b=$b&c=$c";
array group : 분할정보 (division 정보) 미사용시 필요없음
int no => int count
@param part : boolean - 데이타를 group(division) 화 하는지의 여부
@return array
total : 전체 게시물 수
page : 현제 페이지 번호
totalpage : 총 페이지 수
prev_link : 이전 링크
paging : 번호판 리스트
next_link : 다음 링크
start_link : 처음 링크
end_link : 마지막 링크
enable_prev : 이전페이지 가능한가?
enable_next : 다음페이지 가능한가?
object query : group 화 정보 (쿼리용 변수)
int limit : 쿼리에서 사용할 limit
int offset : 쿼리에서 사용할 offset
array group : 쿼리에서 사용할 group number list
*/
public static function paging (array $arr, $part = false)
{
$total = intval($arr['total']);
$page = intval($arr['page']);
$row = intval($arr['row']);
$scale = intval($arr['scale']);
$link = $arr['link'];
$group = $arr['group'];
if($link) $amp = '&';
if($row < 1)
throw new Exception (self::ERR_PAGING_ROW);
if($scale < 1)
throw new Exception (self::ERR_PAGING_SCALE);
if($page < 1) $page = 1;
$totalpage = ceil($total / $row);
if($page > $totalpage) $page = $totalpage;
if($total > 0) {
$start = (intval($page / $scale) * $scale) + 1;
if(!($page % $scale)) $start -= $scale;
$end = $start + $scale - 1;
if($end > $totalpage) $end = $totalpage;
$prev = $start - $scale;
$next = $start + $scale;
}
for($i = $start; $i <= $end; $i++)
$paging_loop[] = array('page_num' => $i,
'page_link' => "page=".$i.$amp.$link);
$count = count($paging_loop);
if($count > 0) $paging_loop[$count-1]['end'] = 1;
$limit = $row;
$offset = ($page - 1) * $row;
if(!$part) {
$_grp->limit = $limit;
$_grp->offset = $offset;
}
else {
if(!is_array($group))
throw new Exception(self::ERR_PAGING_PART_INFO_INVALID);
try {$_grp = self::_make_query_info($group, $limit, $offset); }
catch (Exception $e) { throw $e; }
}
$arr = array('total' => $total,
'page' => $page,
'totalpage' => $totalpage,
'prev_link' => 'page='.$prev.$amp.$link,
'paging' => $paging_loop,
'next_link' => 'page='.$next.$amp.$link,
'start_link' => 'page=1'.$amp.$link,
'end_link' => 'page='.$totalpage.$amp.$link,
'enable_prev' => ($page > $scale) ? true : false,
'enable_next' => ($end < $totalpage) ? true : false,
'query' => $_grp
);
return $arr;
}
private static function _make_query_info(array $grp, $limit, $offset)
{
$start = $offset;
$end = $offset + $limit;
$sum = 0;
$found = false;
$pos = array();
$_offset = 0;
foreach($grp as $part => $count) {
if(!is_int($part) || $part < 1)
throw new Exception(self::ERR_PAGING_PART_NO_NOT_INTEGER);
if(!is_int($count))
throw new Exception(self::ERR_PAGING_PART_COUNT_NOT_INTEGER);
$sum += $count;
if($sum > $start) $found = true;
if($found) {
$pos[] = $part;
if(!$_offset) $_offset = $offset + $count - $sum;
}
if($sum >= $end) break;
}
if(!is_array($pos))
throw new Exception(self::ERR_PAGING_PART_INFO_INVALID);
$group->group = $pos;
$group->offset = $_offset;
$group->limit = $limit;
return $group;
}
public static function get_errmsg ($const)
{
switch($const) {
case self::ERR_PAGING_ROW:
return '페이지당 출력수를 셋팅해 주세요';
case self::ERR_PAGING_SCALE:
return '페이징 블럭을 셋팅해 주세요';
case self::ERR_PAGING_PART_INFO_INVALID:
return '분할정보가 없거나 잘못되었습니다.';
case self::ERR_PAGING_PART_NO_NOT_INTEGER:
return '분할번호가 숫자가 아니거나 없습니다.';
case self::ERR_PAGING_PART_COUNT_NOT_INTEGER:
return '해당분할그룹의 정보가 숫자가 아닙니다.';
default: return '알수 없는 에러입니다.';
}
}
}
// example1 - 그룹화 하지 않은 경우
$arr = array('total' => 5,
'page' => 1,
'row' => 10,
'scale' => 10);
try {$paging = C::paging($arr); }
catch (Exception $e) {
print 'LINE: '.$e->getLine().' '
.C::get_errmsg($e->getmessage());
exit;
}
// pgsql 에서는 limit offset 이 limit $limit offset $offset
// mysql 에서는 limit $offset,$limit
// oracle 에서는 RN between ($offset + 1) and ($offset + $limit)
// 또는 각자 알아서 영역을 구하시길
$query = "select xxxxx from xxxx order by xxx "
."limit ".$paging['query']->limit." offset ".$paging['query']->offset;
$tpl->assign($paging);
// example2 - 그룹화 할 경우 (division 사용시)
// 앞은 분할번호 뒤는 갯수
// 최신정보부터 뒤집어 넣습니다.
$division = array(5 => 205,
4 => 5000,
3 => 5029,
2 => 4800
);
$arr = array('total' => 15034,
'page' => 22,
'row' => 10,
'scale' => 10,
'group' => $division);
try {$paging = C::paging($arr, true); }
catch (Exception $e) {
print 'LINE: '.$e->getLine().' '
.C::get_errmsg($e->getmessage());
exit;
}
$query = "select xxxxx from xxxx "
."where xxxx "
."and division in (".implode(',', $paging['query']->group).") "
."order by xxx "
."limit ".$paging['query']->limit." offset ".$paging['query']->offset;
$tpl->assign($paging);
?>
펌:http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=57690&page=1
'인터넷관련' 카테고리의 다른 글
웹서버에 부하없는.. 실시간 상담용 채팅프로그램 , AJAX (0) | 2007.12.04 |
---|---|
[함수] 'ㅅㅂㄹㅁ','凸' 욕 필터링 (0) | 2007.12.04 |
[알고리즘] 큰 배열에서 검색방법 (0) | 2007.12.04 |
제로보드 스팸광고게시물,덧글 자동등록 방지 ZM_Crypt 2.0 (0) | 2007.12.04 |
cairo graphic library with php (gd 와 비교가 안됩니다.) (0) | 2007.12.04 |
플래쉬 스트리밍 서버 RED5 (무료 - 소스 공개 서버) 설치기 (0) | 2007.12.04 |
[JS] 홈페이지 확대 축소 (0) | 2007.12.04 |
JS Javascript 폼 유효성 검사 라이브러리 MiyaValidator (0) | 2007.11.28 |