반응형

CI4에는 자체적으로 지원해주는 페이징함수가 있다. 이걸 Pager라고 한다. Pager를 이용해서 페이징을 해보자. 우선 리스트에 게시물을 100개 이상 넣어보자. 

https://programmerdaddy.tistory.com/209

 

php+mysql 게시판 만들기 강좌 #16. 회원 게시판 - 페이징

페이징을 하는 방법은 아주 다양하다. 여기서는 그중 가장 쉬운 방법으로 해볼것이다. 우선 데이터를 늘이기위해 아래 쿼리를 디비에서 날려준다. insert into board (`userid`, `subject`, `content`, `regdate`,

programmerdaddy.tistory.com

위 링크에 가보면 이전 페이징도 있으니 참고하고 아래 쿼리를 이용해 데이터를 입력한다.

 

insert into board (`userid`, `subject`, `content`, `regdate`, `status`)
select userid, concat("제목_",right(rand(),6)), concat(content,"_",right(rand(),6)), now(), status from board;

 

한 100개 이상은 넣어주도록 하자. 이제 소스를 수정해보자.

 

/app/Controllers/Board.php

<?php

namespace App\Controllers;
use App\Models\BoardModel;//사용할 모델을 반드시 써줘야한다.

class Board extends BaseController
{
    public function list()
    {
        $db = db_connect();
        $page    = $this->request->getVar('page') ?? 1;//현재 페이지, 없으면 1
        $perPage = 10;//한 페이지당 출력할 게시물 수
        $startLimit = ($page-1)*$perPage;//쿼리의 limit 시작 부분
        $sql = "select b.*, if((now() - regdate)<=86400,1,0) as newid
        ,(select count(*) from memo m where m.status=1 and m.bid=b.bid) as memocnt
        ,(select m.regdate from memo m where m.status=1 and m.bid=b.bid order by m.memoid desc limit 1) as memodate
        ,(select count(*) from file_table f where f.type='board' and f.status=1 and f.bid=b.bid) as filecnt
        from board b where 1=1";
        $order = " order by bid desc";
        $limit = " limit $startLimit, $perPage";
        $query = $sql.$order.$limit;
        $rs = $db->query($query);
        $rs2 = $db->query($sql);
        $total = $rs2->getNumRows();//전체 게시물수

        $data['list'] = $rs->getResult();
        $data['total'] = $total;
        $data['page'] = $page;
        $data['perPage'] = $perPage;

        $pager = service('pager');//페이저를 호출한다.
        $pager_links = $pager->makeLinks($page, $perPage, $total, 'default_full');
        $data['pager_links'] = $pager_links;//페이징을 구현될 부분을 리턴한다.

        return render('board_list', $data);//view에 리턴
    }

    public function write()
    {
        if(!isset($_SESSION['userid'])){
            echo "<script>alert('로그인하십시오.');location.href='/login'</script>";
            exit;
        }
        return render('board_write');  
    }

    public function save()
    {
        if(!isset($_SESSION['userid'])){
            echo "<script>alert('로그인하십시오.');location.href='/login'</script>";
            exit;
        }
        $db = db_connect();
        $bid=$this->request->getVar('bid');//bid값이 있으면 수정이고 아니면 등록이다.
        $subject=$this->request->getVar('subject');
        $content=$this->request->getVar('content');

        if($bid){
            $query = "select * from board where bid=".$bid;
            $rs = $db->query($query);
            if($_SESSION['userid']==$rs->getRow()->userid){
                $sql="update board set subject='".$subject."', content='".$content."' where bid=".$bid;
                $rs = $db->query($sql);
                return $this->response->redirect(site_url('/boardView/'.$bid));
            }else{
                echo "<script>alert('본인이 작성한 글만 수정할 수 있습니다.');location.href='/login';</script>";
                exit;
            }
        }

        //$file = $this->request->getFile('upfile');//첨부한 파일의 정보를 가져온다.
        $files = $this->request->getFileMultiple("upfile"); //다중 업로드 파일 정보
        $filepath = array();
        foreach($files as $file){
            if($file->getName()){//파일 정보가 있으면 저장한다.
                $filename = $file->getName();//기존 파일명을 저장할때 필요하다. 여기서는 사용하지 않는다.
                //$filepath = WRITEPATH. 'uploads/' . $file->store(); 매뉴얼에 나와있는 파일 저장 방법이다.여기서는 안쓴다.
                $newName = $file->getRandomName();//서버에 저장할때 파일명을 바꿔준다.
                $filepath[] = $file->store('board/', $newName);//CI4의 store 함수를 이용해 저장한다. 저장한 파일의 경로와 파일명을 리턴, 배열로 저장한다.
            }
        }

        $sql="insert into board (userid,subject,content) values ('".$_SESSION['userid']."','".$subject."','".$content."')";
        $rs = $db->query($sql);
        $insertid=$db->insertID();
        foreach($filepath as $fp){//배열로 저장한 파일 저장 정보를 디비에 입력한다.
            if(isset($fp)){
                $sql2="INSERT INTO file_table
                        (bid, userid, filename, type)
                        VALUES('".$insertid."', '".$_SESSION['userid']."', '".$fp."', 'board')";
                $rs2 = $db->query($sql2);                
            }
        }
        return $this->response->redirect(site_url('/boardView/'.$insertid));
    }

    public function view($bid = null)
    {
        $db = db_connect();
        $query = "select b.*,(select GROUP_CONCAT(filename) from file_table f where f.bid=b.bid and f.type='board') as fs from board b where b.bid=".$bid;
        $rs = $db->query($query);
        $data['view'] = $rs->getRow();
        return render('board_view', $data);  
    }

    public function modify($bid = null)
    {
        $db = db_connect();
        $query = "select * from board where bid=".$bid;
        $rs = $db->query($query);
        if($_SESSION['userid']==$rs->getRow()->userid){
            $data['view'] = $rs->getRow();
            return render('board_write', $data);  
        }else{
            echo "<script>alert('본인이 작성한 글만 수정할 수 있습니다.');location.href='/login';</script>";
            exit;
        }
       
    }

    public function delete($bid = null)
    {

        $db = db_connect();
        $query = "select * from board where bid=".$bid;
        $rs = $db->query($query);
        if($_SESSION['userid']==$rs->getRow()->userid){
            $query3 = "select * from file_table where type='board' and bid=".$bid;
            $rs3 = $db->query($query3);
            $fs=$rs3->getResult();
            foreach($fs as $f3){
                unlink('uploads/'.$f3->filename);
            }
            $query4 = "delete from file_table where type='board' and bid=".$bid;
            $rs4 = $db->query($query4);
            $query2 = "delete from board where bid=".$bid;
            $rs2 = $db->query($query2);
            return $this->response->redirect(site_url('/board'));
        }else{
            echo "<script>alert('본인이 작성한 글만 삭제할 수 있습니다.');location.href='/login';</script>";
            exit;
        }
    }
}

 

list()부분을 수정했다. 쿼리도 좀 바꿔줬다. 일반 PHP게시판 강의에서 쓰던 쿼리이다. 다른건 보던 것들이니 넘어가고 다음 부분은 확인하자.

 

$pager = service('pager');//페이저를 호출한다.
$pager_links = $pager->makeLinks($page, $perPage, $total, 'default_full');
$data['pager_links'] = $pager_links;//페이징을 구현될 부분을 리턴한다.

 

페이징을 만들어 주는 부분이다. 이렇게 만들어주고 pager_links 값을 화면에 뿌려주면 페이징을 구현할 수 있다. 이제 화면에 나오도록 수정한다.

 

/app/Views/board_list.php

    <table class="table">
        <thead>
            <tr>
            <th scope="col">번호</th>
            <th scope="col">글쓴이</th>
            <th scope="col">제목</th>
            <th scope="col">등록일</th>
            </tr>
        </thead>
        <tbody id="board_list">
  
            <?php
            $idNumber = $total - ($page-1)*$perPage;
            foreach($list as $ls){
            ?>
                <tr>
                    <th scope="row"><?php echo $idNumber--;?></th>
                    <td><?php echo $ls->userid;?></td>
                    <td><a href="/boardView/<?php echo $ls->bid;?>"><?php echo $ls->subject;?></a></td>
                    <td><?php echo $ls->regdate;?></td>
                </tr>
            <?php }?>
        </tbody>
        </table>
        <!-- 페이징 -->
        <div style="padding-top:30px;">
            <?= $pager_links ?>
        </div>
        <p style="text-align:right;">
            <a href="/boardWrite"><button type="button" class="btn btn-primary">등록</button><a>
            <?php
            if(isset($_SESSION['userid'])){
            ?>
                <a href="/logout"><button type="button" class="btn btn-warning">로그아웃</button><a>
            <?php }else{?>
                <a href="/login"><button type="button" class="btn btn-warning">로그인</button><a>
            <?php }?>
        </p>

 

그런데 화면이 내가 생각한것과는 좀 많이 다르다. 왜냐면 지금은 ci4에서 제공해주는 기본적인  템플릿을 사용했기때문이다. 어디서 그런걸 지정했을까?

 

$pager_links = $pager->makeLinks($page, $perPage, $total, 'default_full');

 

바로 이부분이다. 이부분의 맨 마지막에 있는 default_full이 바로 템플릿을 지정하는 부분이다. 여기에 default_full이라고 돼 있으니 ci4에서 기본적으로 제공해주는 템플릿을 보여주었던 것이다. 이런 템플릿이 어디에 지정돼 있는지 확인해보자.

 

/app/Config/Pager.php

 

위 파일을 열어보면 

 

public $templates = [
        'default_full'   => 'CodeIgniter\Pager\Views\default_full',
        'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
        'default_head'   => 'CodeIgniter\Pager\Views\default_head',
    ];

 

이렇게 기본적인 템플릿들이 지정돼 있다는 것을 알 수 있다. 기본 템플릿이 너무 구리니 조금 수정을 해보자.

 

/system/Pager/Views/default_full.php

 

<?php

use CodeIgniter\Pager\PagerRenderer;

/**
 * @var PagerRenderer $pager
 */
$pager->setSurroundCount(2);
?>

<nav aria-label="<?= lang('Pager.pageNavigation') ?>">
    <ul class="pager pagination justify-content-center">
        <?php if ($pager->hasPrevious()) : ?>
            <li class="page-item">
                <a class="page-link" href="<?= $pager->getFirst() ?>" aria-label="<?= lang('Pager.first') ?>">
                    <span aria-hidden="true"><?= lang('Pager.first') ?></span>
                </a>
            </li>
            <li class="page-item">
                <a class="page-link" href="<?= $pager->getPrevious() ?>" aria-label="<?= lang('Pager.previous') ?>">
                    <span aria-hidden="true"><?= lang('Pager.previous') ?></span>
                </a>
            </li>
        <?php endif ?>

        <?php foreach ($pager->links() as $link) : ?>
            <li <?= $link['active'] ? 'class="page-item active"' : '' ?>>
                <a class="page-link" href="<?= $link['uri'] ?>">
                    <?= $link['title'] ?>
                </a>
            </li>
        <?php endforeach ?>

        <?php if ($pager->hasNext()) : ?>
            <li class="page-item">
                <a class="page-link" href="<?= $pager->getNext() ?>" aria-label="<?= lang('Pager.next') ?>">
                    <span aria-hidden="true"><?= lang('Pager.next') ?></span>
                </a>
            </li>
            <li class="page-item">
                <a class="page-link" href="<?= $pager->getLast() ?>" aria-label="<?= lang('Pager.last') ?>">
                    <span aria-hidden="true"><?= lang('Pager.last') ?></span>
                </a>
            </li>
        <?php endif ?>
    </ul>
</nav>
위 파일을 열어서 위와같이 변경한다. 기본 템플릿에 몇가지 클래스를 추가해 주었다. 이렇게 수정 후 다시 리스트 페이지를 확인해보자.
 

 

이제 좀 페이징처럼 보인다. 이렇게 보인다면 성공이다. 안되면 될때까지~

반응형

+ Recent posts