영원한사랑

페이징 함수

인터넷정보2007. 12. 4. 10:03
일반적인것과 그룹화 한 것 두가지 샘플이 있으니 보시면 아실거 같고

리팩토링은 알아서 하시길 바랍니다.
버그있음 댓글달아주세요 (그룹화 해본적이 없어 이런상으로 계산된거라 제대로 나오는지는 모르겠습니다.)

본 코드는 아무렇게가 갖다 쓰심 됩니다.


<?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

페이징

인터넷정보2007. 10. 11. 23:27
<?
$PG_this = $_REQUEST[PG_this];

$PG_line = 201;// 전체 라인 수(=전체 멤버 수)
$PG_unit = 10;                // 페이지당 라인수 : 12줄=1페이지
$PG_grup = 10;                // 한 화면당 나타날 페이지 그룹 갯수 : 10개

$PG_tots = ceil($PG_line / $PG_unit); // 전체 페이지 수

$PG_this = $PG_this ? $PG_this:($PG_tots ? 1:0); // 현재 열린 페이지 또는 0(무효) 계산

$PG_strt = $PG_this ? (floor($PG_this/$PG_grup)*$PG_grup+1):0; // 페이지 그룹 시작페이지 수 계산
if($PG_strt >$PG_this) { $PG_strt -= $PG_grup; }

$PG_fnsh = $PG_strt ? ($PG_strt+$PG_grup-1):0; // 페이지 그룹 최종페이지 수 계산
if($PG_fnsh >=$PG_tots) { $PG_fnsh = $PG_tots; }

$PG_frst = ($PG_strt > $PG_grup*2) ? 1:0; // 첫페이지 그룹 1 또는 0(무효) 계산

$PG_prev = ($PG_strt > $PG_grup) ? ($PG_strt -1):0; // 이전페이지 그룹 계산

$PG_next = (($PG_strt+$PG_grup) <= $PG_tots) ? ($PG_fnsh+1):0; // 다음 페이지 그룹 계산

$PG_last = (($PG_strt+$PG_grup*2) <= $PG_tots) ? ($PG_tots):0; // 마지막 페이지 그룹 계산

// 처음 및 이전 페이지 링크 출력
$PG_link .= $PG_frst ? " <a href=".$_SERVER[PHP_SELF]."?PG_this=$PG_frst>처음</a>":"";
$PG_link .= $PG_prev ? " <a href=".$_SERVER[PHP_SELF]."?PG_this=$PG_prev>이전</a>":"";

// 현재 페이지 그룹 리스트 출력
for($i=$PG_strt; $i<=$PG_fnsh; $i++) {
  if($PG_this == $i) { $PG_link .= " <b>$i</b>"; }
  else { $PG_link .= " <a href=".$_SERVER[PHP_SELF]."?PG_this=$i>$i</a>"; }
}

// 다음 및 마지막 페이지 링크 출력
$PG_link .= $PG_next ? " <a href=".$_SERVER[PHP_SELF]."?PG_this=$PG_next>다음</a>":"";
$PG_link .= $PG_last ? " <a href=".$_SERVER[PHP_SELF]."?PG_this=$PG_last>마지막</a>":"";
// 디비에서 현재 페이지 내용 출력하기

echo $PG_link;
?>

안녕하세요~

오늘은 두번째로 올리는 초급용 씨리즈 입니다.

오늘도 초급용 씨리즈냐고 태클 거신다면.. 그래도 초급용 입니다 -_-;;

할 수 없습니다. 아시는 분은 안보셔도 됩니다 초급용입니다 -_-;;

어제는 js를 이용한 form과 관련한 내용이었는데요

오늘은 많은 초급 phper들이 게시판을 이용해서 공부하면서

가장 힘들어하고 어려워 하는 페이징의 원리를 말씀드릴까 합니다.

페이징 : 통상 이렇게 말하는데요 저는 네비게이터 라고 자주 말합니다.

게시판의 목록에 페이지를 넘겨줄 수 있는 번호 링크를 두고 하는 말이죠..

그럼 시작해 볼까요~


제가 수업시간에 네비게이터를 수업하게 되면 자주 써먹는 과제 중에 하나가

주어진 수의 범위가 있을 때
 ex ) 0~9, 10~19, 20~29

x라는 수를 입력 받으면 어느 범위에 속하는지 알아 내는 문제를 냅니다.

※ 정확히 말하자면 범위의 첫 수를 구해내는 문제입니다. (0 ,10, 20)

자! 시간 5분 드립니다 풀어보세요!

1초
2초
3초
5분 끝!

다 푸셨나요 -0-?

왜 저 문제가 페이징 (네비게이터)와 관련있을까?

우리가 통상 php를 이용하여 프로그램을 제작하면 효율성등등 감안해서 많은

부분을 생각하게 됩니다. 하지만 이런건 숙련자들의 몫이죠 초급자는 아무리

강조해도 이런거 생각 못합니다.

그럼 무엇을 가지고 초급자들이 프로그램을 제작 해야할 까요?

무엇을 보여주고 어떻게 보여줄것인가!! 이게 관건입니다.

같이 문제를 풀어보죠

가령 5라는 수가 입력 되었다고 가정하면

(어이 거기 눈돌리지말고~ 잘봐!! 계산하고있지?)

계산하지마세요 계산은 여러분들이 하는게 아니죠? 서버(컴퓨터)가 해주는거에요

우리는 컴퓨터가 계산할 일정한 규칙성(계산식)을 만들어 주면 됩니다.

그럼 젤 먼저 해야될 일! 바로 변수의 선언입니다. 모든 프로그램에 공통적으로

시작할 때 일단 사용할 변수를 선언해 주는게 프로그램을 작성하면서 변수가 꼬인다거나

잘못된 값을 계산한다거나 하는 일 (버그)를 줄여줍니다.

$psize = 10; //수의 범위 크기 입니다.
$x = 5; //입력받은 수입니다.

5가 어느 범위에 들어갈지 우리 머리속에는 이미 인지하고 있지만

논리적으로 계산식을 만드는 것은 꾀 어렵습니다.

그런데요 잘 생각해 보면 문제안에 항상 답이 있다는 거죠~

범위의 첫수 0, 10, 20 을 구하는 식을 만들자면 5, 15, 25라는 수가 있을 때

일반적인 수학을 생각하면 절대 답 없습니다.

5를 주어진 수의 범위로 일단 나누고 봅시다 0보다는 5가 크니 빼버리면 되겠지만

15가 입력된다면 15를 또 빼줘도 0이 되지 10이되지는 않겠죠?

5-5=0
15-15=0
절대 자기 자신을 빼버려서는 답이 없다!!

그래서 일단 나눠봅시다

5/10 = ? 0.5
15/10 = ? 1.5
25/10 = ? 2.5

음.. 뭔가 비슷한 모양이 나올거 같군요

왜 나누냐고요? 더하거나 곱하면 수거 더 커지지 작아 지지는 않겠죠?

그래서 나누어 봤습니다.

그럼 저렇게 구해진 값을 이제 변수로 지정해 봅시다.

$start_num = $x / $psize;

일단 이런식이 만들어 지겠네요

0.5 , 1.5, 2.5 이렇게 나온 값을 이제 php 내장 객체인 floor를 이용해서

소수점을 버려 봅시다!

$start_num = floor($x / $psize);

하니까 x의 값이 달라질 때 마다 0, 1, 2 라는 수를 start_num이 가지게 되겠죠?

그런데~ 여기서 끝난게 아닙니다. 0, 10, 20 이렇게 되도록 하고 싶은데요

저런 수에다가 주어진 범위의 크기만큼 곱셈을 하면 어떻게 될까요?

그렇습니다~

$start_num = floor($x / $psize) * $psize;

0은 아무리 큰수를 곱해도 0이고 1곱하기 10은 10, 2곱하기 10은 20이니

우리가 원하는 범위의 첫번째 수를 구하는 것을 해결했습니다.

그럼 저 공식이 왜 필요한가?

보여주는 숫자를 보니 1부터 시작하는데... 페이지 번호는 0번부터라니..

이상하자나요~ 하고 질문하는 학생 꼭 있습니다!!

그건 바로 배열과 관련된 부분과 물질수의 10진수와 수학의 10진수는

항상 1의 갭이 있다는걸 생각해야 합니다.

우리가 통상 사용하는 물질수의 10진수는 1,2,3,~10 이 겠지만

수학에서의 10진수는 0~9까지의 수를 말합니다.

그럼 배열은? 배열에서 자동으로 부여되는 (php를 포함한 특정 언어만) 인덱스 key는

0부터 시작합니다. 물론 10진수고요.


자 이제 1단계 과제가 해결되었습니다.

※ 2단계 과제
주어진 글의 개수가 534개다 페이지당 10개씩 보여준다면
페이지는 총 몇개의 페이지가 되는가?

음.. 어렵나요? 쉽죠?

10개씩 보여준다면야 당연히 10으로 나누면 총 페이지의 갯수가 나오는데요

여기서 놓치기 쉬운 부분이 마지막에 남는 글의 갯수랍니다.

534/10=? 53.4

그럼 페이지 수가 53.4개라는건데 소수점은 어떻게 해주는게 좋을까요?

그렇습니다~ 바로 소수점 무조건 올림인 ceil 함수를 이용하여

올림수인 54페이지를 만들어 줘야 마지막에 남는 0.4페이지분량의 글을

모두 보여줄 수 있다는거죠


그럼 총 페이지의 개수도 구했습니다.

이제 해야할 마지막 관문!!!

※ 문제3 그럼 한 화면에 10개씩 페이지 번호를 보여준다면
이런 단위블럭이 몇개가 나오나요?

위 문제와 유사하죠? 그렇습니다 3번문제가 요구하는 것은

네비게이터의 이전 , 다음 링크를 만들기 위한 조건으로 사용될 일정한 값을

구하기 위한 문제 입니다.

그럼 실질적 아래 예제 코드를 이용해서 확인해 복습해 봅시다.


<?
$start = $_GET[start];
$total = 534;//총 레코드수
$scale = 10;//페이지당 출력 레코드수
$page_scale = 10; // 화면당 출력할 페이지 수
if(!$start) $start = 0;//시작 페이지 번호가 없을경우 0

$total_page = ceil($total/$scale);//총 페이지수
$page = floor($total_page/$page_scale);//단위블럭페이지수
$n_page = floor($start/$page_scale);//현재 단위블럭 페이지번호

if($n_page > 0){
//이전 링크 출력 조건 현재단위블럭 페이지 번호가 0보다 클경우
    $p_start = ($n_page-1)*$page_scale;
//현재 단위블럭 페이지 -1 * 단위블럭 페이지 출력수(page_scale)
    $link = "<a href='".$_SERVER[PHP_SELF]."?start=${p_start}'>";
    $link .= "이전";
    $link .= "</a>";
    echo $link." ";
}
$is = $n_page*$page_scale;//단위블럭 페이지 시작번호 구하기 현재 페이지 번호를 이용하여 현재 단위블럭 페이지 번호를 구하고 그 값을 이용하여 단위블럭 페이지 출력수를 곱한 값
for($i=$is; $i < $is+$page_scale; $i++){
//i는 현재 단위블럭 페이지 번호*단위블럭 페이지 출력수 부터 시작하고 i는 단위블럭 페이지 출력수를 더한 값만큼만 반복하도록 지정
    if($i < $total_page){//i가 총 페이지수 보다 작을 동안만 출력하기 위한조건
        $link = "<a href='".$_SERVER[PHP_SELF]."?start=${i}'>";
        $link .= $i+1;//start값이 i로 지정됨으로 화면상 출력기준을 1부터 시작하는 10진수로 맞추기 위해 +1을 연산
        $link .= "</a>";
        echo $link." ";
    }
}

if($n_page < $page){//현재 단위블럭 페이지번호 보다 총 단위블럭 페이지 수가 작을 경우에만 다음 링크 출력
    $link = "<a href='".$_SERVER[PHP_SELF]."?start=${i}'>";//i는 상단 for문에서 이미 마지막 페이지 start번호보다 +1한 값을 가지고 있기 때문에 i를 그냥 출력함
    $link .= "다음";
    $link .= "</a>";
    echo $link;
}

?>



어떠셨나요?

선행 학습내용을 잘 읽어 보신분이라면 쉽게 이해가 되었을 것입니다.

선행 학습내용만 잘 이해한다면 어떠한 언어로로 페이징은 만들어 낼 수 있습니다.

코드가 중요한게 아니라 바로 로직 or 알고리즘이 중요하다는거 잊지맙시다.

if($_GET["page"]) $page = $_GET["page"]; // 현재 페이지 구하기
else $page = 1;

$total = 980; // 총 게시물 수
$pg_scale = 10; // 한페이지에 출력 될 목록 수
$pg_group = 20; // 보여질 페이지 수 ([1][2][3]이런거)
$pg_select = ($page - 1) * $pg_scale;
$pg_total = ceil($total / $pg_scale); // 총 페이지 수 구하기
$pg_half = floor($pg_group/2);

echo "<a href='?page=1'>처음</a> "; // 첫 페이지
$pg_half3 = $page>($pg_total-5) ? 10-($pg_total-$page) : $pg_half;
for($i=0;$i<$pg_half3;$i++) {
    $j = $page - $pg_half3 + $i;
    if($j > 0) {
        echo " <a href='?page=$j'>$j</a> "; // 현재 페이지의 앞페이지들
    }
}
echo " <b>$page</b> "; // 현재 페이지
$pg_half2 = $page<5 ? 10-$page : $pg_half;
for($i=0;$i<$pg_half2;$i++) {
    $j = $page + $i + 1;
    if($j <= $pg_total) {
        echo " <a href='?page=$j'>$j</a> "; // 현재 페이지의 뒷페이지들
    }
}
echo " <a href='?page=$pg_total'>끝</a>"; // 끝 페이지

페이징

인터넷정보2007. 10. 11. 22:09

<?php
$page = $_REQUEST["page"];
if(!$page) $page = 1;

$total_num = 151;  // 전체 레코드수
$pagesize = 10; // 페이지 당 뿌릴 레코드 수
$pagePerBlock = 10; // [1] ~ [10] 까지 한번에 10개씩
$search = "&search=문자"; //GET 방식으로 추가 문자열을 넣는다
function handlePage($total_num,$pagesize,$pagePerBlock,$page,$search){ // 전체레코드,  페이지당 레코드수(10) , 블럭당페이지수(10), 현재페이지

    $totalNumOfPage = ceil($total_num/$pagesize); //16page
    $totalNumOfBlock = ceil($totalNumOfPage/$pagePerBlock); //2block
    $currentBlock = ceil($page/$pagePerBlock); // 1page
       
    $startPage = ($currentBlock-1)*$pagePerBlock+1;  // 1page
    $endPage = $startPage+$pagePerBlock -1; // 10page
    if($endPage > $totalNumOfPage) $endPage = $totalNumOfPage;
   
    //NEXT,PREV 존재 여부
    $isNext = false;
    $isPrev = false;
   
    if($currentBlock < $totalNumOfBlock)    $isNext = true;
    if($currentBlock > 1)                    $isPrev = true;
   
    if($totalNumOfBlock == 1){
        $isNext = false;
        $isPrev = false;
    } 
   
    if($isPrev){
        $goPrevPage = $startPage-$pagePerBlock; // 11page
        echo "<a href=\"$PHP_SELF?page=$goPrevPage$search\">◀</a>";       
    }else{
        echo "◀";
    }
    for($i=$startPage;$i<=$endPage;$i++){
        if($page==$i){
            echo "<b>[".$i."]</b>";
        }else{
            echo "<a href=\"$PHP_SELF?page=$i$search\">[".$i."]</a>";
        }
    }
    if($isNext){
        $goNextPage = $startPage+$pagePerBlock; // 11page
        echo "<a href=\"$PHP_SELF?page=$goNextPage$search\">▶</a>";
    }else{
        echo "▶";
    }
}

handlePage($total_num,$pagesize,$pagePerBlock,$page,$search);
?>

페이징 함수

인터넷정보2007. 10. 11. 22:05

/**
 * 페이징 함수
 *
 * @author Woo,Yeon-geun <cjdma@cjdma.com>
 *
 * @param int $total;
 * @param int $now;
 * @param int $page;
 * @param int $scale;
 * @param int $block_scale;
 *
 * @return int  $prev  이전 페이지
 * @return int  $page  현재 페이지
 * @return int  $next  다음페이지
 * @return int  $first 시작할 때의 글번호
 * @return array $range 출력하려는 페이지들
 */
function OBS_pubPaging($param)
{
    $total      = $param['total'];
    $now        = $param['now'];
    // 현재페이지 (없으면 1)
    $page        = $param['page']        ? $param['page']        :  1;
    // 한 페이지에 출력하는 row수
    $scale      = $param['scale']      ? $param['scale']      : 20;
    // 한 페이지에 화면에 출력하는 페이지수 ([prev] 1.2.3.4.5 [next] <- 이 때는 block_scale '5')
    $block_scale = $param['block_scale'] ? $param['block_scale'] : 10;

    // $now(현재글번호)가 들어올 경우 $now값을 가지고 몇번째 페이지인지 알아내기 (공식 : floor(($now - 1) / $scale) * $scale)
    if($now) {
        $page = $now ? floor(($now - 1) / $scale) : $page;
    }

    // 전체 페이지 수
    $pages = ceil($total / $scale);

    // 현재페이지에서의 첫글번호, 끝글번호
    $begin_page = $block_scale * ($page - 1);
    $end_page  = $block_scale *  $page;

    // 첫번째블럭번호, 마지막블럭번호 (5,6,7,8,9 <- 여기서 $begin=5, $end=9)
    $begin = floor($page / $block_scale) * $block_scale;
    $end  = $begin + $block_scale;

    // 출력될 때의 글번호 10,9,8,7... <- 여기서 first는 '10'
    $first = $total - ($scale * ($page - 1));

    // 내부적으로 시작값이 '0'인 변수를 '1'로 맞추기...
    $begin++;

    // 블럭내 끝  record($end)가 전체값($total)을 넘을 수 없으므로...
    if($end > $pages) { $end = $pages; }
    if($end == 0)    { $end = 1; }

    // prev 5.6.7.8.9 next - 이 경우에 array(5,6,7,8,9)
    $range = range($begin, $end);
    // prev(이전페이지)출력 - $page가    1이 아닐 때
    if($page != 1)
        { $prev = $page - 1; }
    // next(다음페이지)출력 - $page가 $end가 아닐 때
    if($page != $pages && $end != 1)
        { $next = $page + 1; }

    $return['prev']  = $prev;
    $return['page']  = $page;
    $return['next']  = $next;
    $return['range'] = $range;
    $return['first'] = $first;

    return $return;
} // function
-------------------------------------------------------------------------------
사용예...


[ 로직부분 ]
$url  = 'OpenBBS.com/bbs_list.php';
$total = 98; // 전체 글 수
$page  = 1;  // 현재 페이지
$scale = 10; // 한페이지에 나타낼 글의 수
$block_scale = // 하단에 나타낼 페이지 수 ( prev 1.2.3.4.5 next ) <- 이럴 경우 $block_scale은 5

// 변수들을 하나로 묶어서
$param = compact('url', 'total', 'page', 'scale', 'block_scale');
// 페이징 함수에 넣는거죠~ ^^
$pub['paging'] = @OBS_pubPaging($param);
// 리턴된 값은 파씽~
$smarty->assign('pub', $pub);


[ 화면 ]
<!-- 페이징 : B -->
<div id="paging">
{if $pub.paging.prev}
    <a href="{$url.bbs_list}&page={$pub.paging.prev}">prev</a>
{/if}

{foreach from=$pub.paging.range key=key item=value}
    {if $value != $pub.paging.page}
        [<a href="{$url.bbs_list}&page={$value}">{$value}</a>]
    {else}
        [{$value}]
    {/if}
{/foreach}

{if $pub.paging.next}
    <a href="{$url.bbs_list}&page={$pub.paging.next}">next</a>
{/if}
</div>
<!-- 페이징 : E -->