본문 바로가기
코드이그나이터4 [php5][mysql]

코드이그나이터4, 페이징 기술

1. 오토셋 APM 인스톨러 ( apache + php7.2 + mariadb ) 설치 | https://itadventure.tistory.com/93

2. 코드이그나이터 4 ( codeigniter 4 ) 설치 | https://itadventure.tistory.com/95

3. 비주얼 스튜디오 코드 에디터 설치 & 한글 설정 | https://itadventure.tistory.com/96

4. 폴더열기 / 웹페이지 편집(1) | https://itadventure.tistory.com/97

5. 웹페이지 편집(2) | https://itadventure.tistory.com/101

6. 코드이그나이터4의 URL 규칙 | https://itadventure.tistory.com/105

7. php, 네임스페이스 [ namespace ] ?! | https://itadventure.tistory.com/118

8. 코드이그나이터의 네임스페이스, 그리고 모델 | https://itadventure.tistory.com/122

9. 코드이그나이터 뷰의 파라미터 전달 | https://itadventure.tistory.com/147

10. 코드이그나이터 뷰를 나눠 볼까요? | https://itadventure.tistory.com/174

11. MYSQL 이 뭐여? [ 마이에스큐엘은 서류철이다! ] | https://itadventure.tistory.com/175

12. MYSQL 콘솔에 접속해보자! | https://itadventure.tistory.com/178

13. MySql에 넣었다가 꺼냈다가, 뭘? | https://itadventure.tistory.com/265

14. 검색진열대 MYSQL | https://itadventure.tistory.com/267

15. 편집의 왕자 MySQL | https://itadventure.tistory.com/269

16. 코드이그나이터4, MYSQL과 손잡다. | https://itadventure.tistory.com/271

17. MySQL -> 컨트롤러 -> 뷰 트리플 패스! | https://itadventure.tistory.com/272

18. 코드이그나이터! MySQL 에 입력하다! ( insert ) | https://itadventure.tistory.com/273

19. 해킹을 막아라! MySQL인젝션 보안 | https://itadventure.tistory.com/274

20. MySQL과 친해지는 phpmyadmin | https://itadventure.tistory.com/277

21. 코드이그나이터4에서 책 정보를 편집해볼까요? | https://itadventure.tistory.com/280

22. 코드이그나이터4에서 책을 지워봅시다. DELETE! | https://itadventure.tistory.com/282

23/ 코드이그나이터4, 페이징 기술


이번 챕터에서는 페이징 기능을 다뤄보려고 합니다.
만약 책이 몇백권씩 있다면 모든 책을 화면 안에 보여 줄 수 없을 겁니다.
당연히 웹 화면을 한번에 훌쩍 넘어가 버리겠지요?

그럴 때는 관리자 또는 사용자에게 한 화면에 몇개씩 끊어서 일부분을 보여주는 것이 좋습니다.
실제로 이번에 만들 화면은 아래와 같습니다.

책이 100권이 넘는 상황이어서 한 페이지당 200개씩 보여줍니다. 그리고 각 페이지 번호를 클릭하면 해당 페이지로 이동하는 것이지요.

그냥 전체 책목록이 한번에 나와서 한 줄씩 넘겨서 보는것도 나쁘지는 않겠지만 
사실 페이지 나누기는 페이지 로딩 시간을 단축시키기 위한 기술입니다.

책이 100권이 아니라 몇십만권이 넘는 상황이라면 페이지 로딩 시간이 5분~10분이 넘어갈지도 모르는 일이니까요.
그러다 보면 페이지가 너무 늦게 떠 관리자가 짜증나서 '에잇!'하고 잠시 화장실(?)에 다녀올지도 모르는 일이지요 :)

책 목록의 갯수가 너무 적으니까
이번에는 다른 출판사의 책 목록을 가져오도록 하겠습니다.
"이지스 퍼블리싱"이라는 출판사에서 제공하는 도서 목록인데 엑셀로 다운받아 갈 수 있도록 제공하고 있습니다.
괜찮은 책이 많은 듯 한데 관심 분야 있으시면 한번 구매해보시는 것도 권장해 드립니다.

http://www.easyspub.co.kr/11_Menu/BookDown/PUB#ItBook

이 책 목록을 강좌에서 활용할 수 있도록 SQL 문으로 가공하였습니다.
아래 상자안의 내용을 복사하신 다음에,

insert into book (title, totalpage, author) values ('Do it! 타입스크립트 프로그래밍', 408, '전예홍');

insert into book (title, totalpage, author) values ('Do it! 키트 없이 만드는 아두이노', 288, '박필준');

insert into book (title, totalpage, author) values ('Do it! 첫 파이썬', 268, '엘리스 코딩');

insert into book (title, totalpage, author) values ('Do it! 키트 없이 만드는 아두이노', 288, '박필준');

insert into book (title, totalpage, author) values ('된다! 네이버 블로그 & 포스트 - 개정 3판', 328, '황윤정');

insert into book (title, totalpage, author) values ('된다! 네이버 블로그 & 포스트 - 개정 3판', 328, '황윤정');

insert into book (title, totalpage, author) values ('[PDF북] 된다! 김메주의 유튜브 영상 만들기 - 전면 개정판', 392, '김혜주');

insert into book (title, totalpage, author) values ('[PDF북] 된다! 파워포인트 실무의 신', 456, '김지훈, 김봉정, 박성용');

insert into book (title, totalpage, author) values ('Do it! 타입스크립트 프로그래밍', 408, '전예홍');

insert into book (title, totalpage, author) values ('Do it! 리액트 프로그래밍 정석', 656, '박호준');

insert into book (title, totalpage, author) values ('Do it! 안드로이드 앱 프로그래밍 전면 개정 7판(안드로이드 10)', 848, '정재곤');

insert into book (title, totalpage, author) values ('Do it! 스위프트로 아이폰 앱 만들기 입문 - 개정 4판', 696, '송호정, 이범근');

insert into book (title, totalpage, author) values ('기계는 어떻게 생각하는가?', 448, '숀 게리시');

insert into book (title, totalpage, author) values ('Do it! HTML5+CSS3 웹 표준의 정석 - 전면 개정 2판', 552, '고경희');

insert into book (title, totalpage, author) values ('Do it! 지옥에서 온 문서 관리자 깃&깃허브 입문', 272, '이고잉, 고경희');

insert into book (title, totalpage, author) values ('Do it! 스위프트로 아이폰 앱 만들기 입문 - 개정 4판', 696, '송호정, 이범근');

insert into book (title, totalpage, author) values ('기계는 어떻게 생각하는가?', 448, '숀 게리시');

insert into book (title, totalpage, author) values ('된다! 김메주의 유튜브 영상 만들기 - 전면 개정판', 392, '김혜주');

insert into book (title, totalpage, author) values ('Do it! 지옥에서 온 문서 관리자 깃&깃허브 입문', 272, '이고잉, 고경희');

insert into book (title, totalpage, author) values ('Do it! 첫 코딩', 276, '정동균');

insert into book (title, totalpage, author) values ('Do it! 웹 사이트 따라 만들기', 312, '김윤미');

insert into book (title, totalpage, author) values ('된다! 파워포인트 실무의 신', 456, '김지훈, 김봉정, 박성용');

insert into book (title, totalpage, author) values ('Do it! 웹 사이트 따라 만들기', 312, '김윤미');

insert into book (title, totalpage, author) values ('Do it! 첫 코딩', 276, '정동균');

insert into book (title, totalpage, author) values ('된다! 맥북&아이맥 - 맥OS 카탈리나 판', 352, '김기백, 조영빈, 이민호, 정다운');

insert into book (title, totalpage, author) values ('Do it! 정직하게 코딩하며 배우는 딥러닝 입문', 328, '박해선');

insert into book (title, totalpage, author) values ('된다! 7일 실무 엑셀', 440, '한정희');

insert into book (title, totalpage, author) values ('Do it! 점프 투 파이썬 - 전면 개정판', 360, '박응용');

insert into book (title, totalpage, author) values ('Do it! 코틀린 프로그래밍', 680, '황영덕');

insert into book (title, totalpage, author) values ('Do it! 점프 투 파이썬 - 전면 개정판', 360, '박응용');

insert into book (title, totalpage, author) values ('Do it! 코틀린 프로그래밍', 680, '황영덕');

insert into book (title, totalpage, author) values ('Do it! 오토캐드 2020', 584, '박한울');

insert into book (title, totalpage, author) values ('Do it! 오토캐드 2020', 584, '박한울');

insert into book (title, totalpage, author) values ('된다! 귀염뽀짝 이모티콘 만들기', 328, '정지혜');

insert into book (title, totalpage, author) values ('Do it! 웹 프로그래밍을 위한 자바스크립트 기본 편', 352, '고경희');

insert into book (title, totalpage, author) values ('Do it! 안드로이드 앱 프로그래밍 전면 개정 6판(파이)', 848, '정재곤');

insert into book (title, totalpage, author) values ('된다! 귀염뽀짝 이모티콘 만들기', 328, '정지혜');

insert into book (title, totalpage, author) values ('Do it! 자료구조와 함께 배우는 알고리즘 입문 - 자바 편', 432, '보요 시바타');

insert into book (title, totalpage, author) values ('된다! 네이버 블로그 & 포스트 - 개정 2판', 328, '황윤정');

insert into book (title, totalpage, author) values ('Do it! 안드로이드 앱 프로그래밍 전면 개정 6판(파이)', 848, '정재곤');

insert into book (title, totalpage, author) values ('Do it! 웹 프로그래밍을 위한 자바스크립트 기본 편', 352, '고경희');

insert into book (title, totalpage, author) values ('Do it! 스위프트로 아이폰 앱 만들기 입문 - 개정 3판', 688, '송호정, 이범근');

insert into book (title, totalpage, author) values ('Do it! 스위프트로 아이폰 앱 만들기 입문 - 개정 3판', 688, '송호정, 이범근');

insert into book (title, totalpage, author) values ('된다! 포토샵&일러스트레이터 CC 2019', 368, '박길현, 이현화');

insert into book (title, totalpage, author) values ('Do it! 자료구조와 함께 배우는 알고리즘 입문 - C 언어 편', 464, '보요 시바타');

insert into book (title, totalpage, author) values ('된다! 포토샵&일러스트레이터 CC 2019', 368, '박길현, 이현화');

insert into book (title, totalpage, author) values ('된다! 맥북&아이맥 -맥OS 모하비판', 368, '김기백, 조영빈, 이민호');

insert into book (title, totalpage, author) values ('된다! 맥북&아이맥 - 맥OS 모하비판', 368, '김기백, 조영빈, 이민호');

insert into book (title, totalpage, author) values ('Do it 오라클로 배우는 데이터베이스 입문', 528, '이지훈');

insert into book (title, totalpage, author) values ('Do it 오라클로 배우는 데이터베이스 입문', 528, '이지훈');

insert into book (title, totalpage, author) values ('Do it! 데이터 분석을 위한 판다스 입문 [전자책]', 280, '다니엘 첸(Chen, Daniel Y.)');

insert into book (title, totalpage, author) values ('Do it! 데이터 분석을 위한 판다스 입문', 280, '다니엘 첸(Chen, Daniel Y.)');

insert into book (title, totalpage, author) values ('된다! 일당백 마케터의 업무 자동화', 268, '박주훈, 황준식');

insert into book (title, totalpage, author) values ('Do it! 자바 프로그래밍 입문', 596, '박은종');

insert into book (title, totalpage, author) values ('Do it! 자바 프로그래밍 입문', 596, '박은종');

insert into book (title, totalpage, author) values ('된다! 일당백 마케터의 업무 자동화', 268, '박주훈, 황준식');

insert into book (title, totalpage, author) values ('Do it! 자바스크립트 + 제이쿼리 - 전면 개정판', 400, '정인용');

insert into book (title, totalpage, author) values ('Do it! 오토캐드 2019', 584, '박한울');

insert into book (title, totalpage, author) values ('데이터 과학, 무엇을 하는가?', 328, '김옥기');

insert into book (title, totalpage, author) values ('데이터 과학, 무엇을 하는가?', 328, '김옥기');

insert into book (title, totalpage, author) values ('Do it! 자료구조와 함께 배우는 알고리즘 입문 - 자바 편', 432, '보요 시바타');

insert into book (title, totalpage, author) values ('Do it! 오토캐드 2019', 584, '박한울');

insert into book (title, totalpage, author) values ('Do it! 자바스크립트 + 제이쿼리 - 전면 개정판', 400, '정인용');

insert into book (title, totalpage, author) values ('Do it! 안드로이드 앱 프로그래밍 - 개정 5판', 848, '정재곤');

insert into book (title, totalpage, author) values ('블록체인 무엇인가?', 316, '다니엘 드레셔');

insert into book (title, totalpage, author) values ('Do it! 프런트엔드 웹 디자인 입문 - 전면 개정판', 368, '고경희');

insert into book (title, totalpage, author) values ('된다! 김메주의 유튜브 영상 만들기', 368, '김혜주');

insert into book (title, totalpage, author) values ('된다! 김메주의 유튜브 영상 만들기', 368, '김혜주');

insert into book (title, totalpage, author) values ('Do it! 프런트엔드 웹 디자인 입문 - 전면 개정판', 368, '고경희');

insert into book (title, totalpage, author) values ('블록체인 무엇인가?', 316, '다니엘 드레셔');

insert into book (title, totalpage, author) values ('Do it! Vue.js 입문', 232, '장기효');

insert into book (title, totalpage, author) values ('Do it! 안드로이드 앱 프로그래밍 - 개정 5판', 848, '정재곤');

insert into book (title, totalpage, author) values ('Do it! Vue.js 입문', 232, '장기효');

insert into book (title, totalpage, author) values ('Do it! 자료구조와 함께 배우는 알고리즘 입문 - C 언어 편', 464, '보요 시바타');

insert into book (title, totalpage, author) values ('Do it! 스위프트로 아이폰 앱 만들기 입문 - 개정 2판', 656, '송호정, 이범근');

insert into book (title, totalpage, author) values ('Do it! 오토캐드 2018', 584, '박한울');

insert into book (title, totalpage, author) values ('[절판] Do it! 스위프트로 아이폰 앱 만들기 입문 - 개정 2판', 656, '송호정, 이범근');

insert into book (title, totalpage, author) values ('된다! 맥북&아이맥 - 맥OS 하이 시에라 판', 352, '김기백, 조영빈, 이민호');

insert into book (title, totalpage, author) values ('Do it! 오토캐드 2018', 584, '박한울');

insert into book (title, totalpage, author) values ('Do it! 자바스크립트+제이쿼리 입문', 572, '정인용');

insert into book (title, totalpage, author) values ('[절판] Do it! 프런트엔드 웹 디자인 입문', 360, '고경희');

insert into book (title, totalpage, author) values ('Do it! C 언어 입문', 576, '김성엽');

insert into book (title, totalpage, author) values ('Do it! Node.js 프로그래밍 <전면 개정판>', 704, '정재곤');

insert into book (title, totalpage, author) values ('된다! 일러스트레이터 CC', 320, '모나미');

insert into book (title, totalpage, author) values ('Do it! 레빗', 368, '장동수');

insert into book (title, totalpage, author) values ('Do it! HTML5+CSS3 웹 표준의 정석 <개정판>', 608, '고경희');

insert into book (title, totalpage, author) values ('Do it! AutoCAD 오토캐드 2016', 680, '박한울, 이정아');

insert into book (title, totalpage, author) values ('Do it! AutoCAD 오토캐드 2015', 680, '김혜영, 박한울');

insert into book (title, totalpage, author) values ('Do it! AutoCAD 오토캐드 2014', 680, '문용삼 ‧ 김혜영‧ 박한울');

insert into book (title, totalpage, author) values ('Do it! AutoCAD 오토캐드 2013', 532, '문용삼‧김혜영');

insert into book (title, totalpage, author) values ('된다! 파워포인트 능력자', 472, '김지훈,박성용,김봉정');

insert into book (title, totalpage, author) values ('된다! 엑셀 능력자', 496, '김철');

insert into book (title, totalpage, author) values ('Do it! 쉽게 배우는 R 데이터 분석', 376, '김영우');

insert into book (title, totalpage, author) values ('된다! 블로그 & 포스트', 300, '황윤정');

insert into book (title, totalpage, author) values ('Do it! 웹 사이트 기획 입문', 392, '이정원');

insert into book (title, totalpage, author) values ('Do it! 웹 사이트 기획 입문', 392, '이정원');

insert into book (title, totalpage, author) values ('Do it! 쉽게 배우는 R 데이터 분석', 376, '김영우');

insert into book (title, totalpage, author) values ('된다! 일러스트레이터 CC', 320, '모나미');

insert into book (title, totalpage, author) values ('DCM 일본 프로 사진가의 테크닉 모음집 [세트]', 2544, '미즈노 카츠히코 외');

insert into book (title, totalpage, author) values ('Do it! 반응형 웹 만들기', 344, '김운아');

insert into book (title, totalpage, author) values ('Do it! Node.js 프로그래밍 <전면 개정판>', 704, '정재곤');

insert into book (title, totalpage, author) values ('[절판] Do it! 안드로이드 앱 프로그래밍 <전면 개정 4판>', 848, '정재곤');

insert into book (title, totalpage, author) values ('된다! 마케팅 자동화', 360, '박주훈, 황준식');

insert into book (title, totalpage, author) values ('Do it! C 언어 입문', 576, '김성엽');

insert into book (title, totalpage, author) values ('된다! 블로그 & 포스트', 300, '황윤정');

insert into book (title, totalpage, author) values ('Do it! 레빗', 368, '장동수');

insert into book (title, totalpage, author) values ('프로 사진가들의 아름다운 사진 촬영법', 424, '하기하라 시로 외');

insert into book (title, totalpage, author) values ('된다! 엑셀 능력자', 496, '김철');

insert into book (title, totalpage, author) values ('된다! 팟캐스트&유튜브 실전 제작법', 256, '김창현, 한지환');

insert into book (title, totalpage, author) values ('Do it! HTML5+CSS3 단기완성', 344, '고경희');

insert into book (title, totalpage, author) values ('프로 사진가들이 알려주는 사진 촬영 특강', 424, '후쿠다 켄타로 외');

insert into book (title, totalpage, author) values ('프로 사진가들의 사진 보정과 렌즈 활용법', 424, '이시다 아키히사 외');

insert into book (title, totalpage, author) values ('Do it! 쉽게 배우는 웹앱&하이브리드앱<전면 개정 2판>', 696, '김응석');

insert into book (title, totalpage, author) values ('데이터 과학, 어떻게 기업을 바꾸었나?', 320, '김옥기');

insert into book (title, totalpage, author) values ('빅데이터, 승리의 과학', 304, '고한석');

insert into book (title, totalpage, author) values ('프로 사진가들이 사용하는 노출과 조리개값', 424, '요코기 아라오 등저');

insert into book (title, totalpage, author) values ('[절판] Do it! 프런트엔드 웹 디자인 입문', 360, '고경희');

insert into book (title, totalpage, author) values ('Do it! AutoCAD 오토캐드 2016', 680, '박한울, 이정아');

insert into book (title, totalpage, author) values ('Do it! 쉽게 만드는 워드프레스 웹사이트', 520, '이태원');

insert into book (title, totalpage, author) values ('프로 사진가 92명의 사진 구도와 풍경사진', 424, '하기하라 시로 외 91인');

insert into book (title, totalpage, author) values ('전문 사진가 68명의 실전 촬영법', 424, '미즈노 카츠히코 외 67인');

insert into book (title, totalpage, author) values ('빅데이터의 다음 단계는 예측 분석이다', 408, '에릭 시겔');

insert into book (title, totalpage, author) values ('프레지 완전활용법 - 전면개정판', 384, '레터릭쇼');

insert into book (title, totalpage, author) values ('Do it! 쉽게 배우는 웹앱&하이브리드앱-전면 개정판', 688, '김응석');

insert into book (title, totalpage, author) values ('Do it! 자바스크립트+제이쿼리 입문', 572, '정인용');

insert into book (title, totalpage, author) values ('Do it! AutoCAD 오토캐드 2015', 680, '김혜영, 박한울');

insert into book (title, totalpage, author) values ('Do it! AutoCAD 오토캐드 2014', 680, '문용삼 ‧ 김혜영‧ 박한울');

insert into book (title, totalpage, author) values ('삼성 NX 스마트 카메라 미러리스로 찍는 사진의 마법', 272, '변현우');

insert into book (title, totalpage, author) values ('네이버 검색 1위 만들기', 224, '황홍식, 김혜원, 권오원');

insert into book (title, totalpage, author) values ('프로페셔널 사진의 조건, 라이트룸5', 588, '백종수(주산지)');

insert into book (title, totalpage, author) values ('프로페셔널 사진의 조건! 스트로보, 외장플래시', 332, '도영찬');

insert into book (title, totalpage, author) values ('빅데이터, 승리의 과학', 304, '고한석');

insert into book (title, totalpage, author) values ('미러리스 & 하이브리드 카메라 입문', 384, '박기덕');

insert into book (title, totalpage, author) values ('니콘 DSLR 카메라 입문', 432, '박기덕');

insert into book (title, totalpage, author) values ('파나소닉 루믹스 G로 찍는 사진의 마법 [개정판]', 208, '변현우, 배호종');

phpMyAdmin 페이지에 접속하셔서 library 데이터베이스 선택, SQL 탭 선택, 상자안에 복사하신 내용을 붙여넣으신 다음 실행 버튼을 눌러주시면 됩니다.

1 열이 적용되었다고 나오는데 뭐 신경쓰지 않으셔도 됩니다. 제일 마지막 줄에 있는 insert 문의 실행결과를 보여주는 것이니까요.

이제 책 목록 페이지에 접속해보겠습니다. 한 화면을 훌쩍 넘어가는 페이지이기 때문에 오른쪽에 스크롤바가 생겼군요.
100권 정도야 금방 가볍게 뜨겠지만 몇십만권이라면, 몇분이 소요될 수도 있습니다.

http://localhost/bookList

이제 새로운 페이징 기능이 적용된 책 목록 페이지를 만들어 볼텐데요.
BookList 페이지는 그대로 놔두고 BookList2 페이지를 만들어보도록 합시다.
아래와 같이 소스를 구성해 주세요

CodeIgniter4\App\Controllers\BookList2.php

<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class BookList2 extends Controller
{
    public function index()
    {
        $db = \Config\Database::connect("default", false);
        $pageview=20;
        $page=$this->request->getVar("page");
        if($page=="")$page=1;
        $startlimit=($page-1)*$pageview;
        $query_count = $db->query("SELECT count(*) FROM book");
        $results_count = $query_count->getResultArray();
        $total = $results_count[0]['count(*)'];
        $totalpage = ceil($total / $pageview);
        $pagestr="{$total}건, {$totalpage}페이지 / ";
        for($i=1;$i<=$totalpage;++$i){
            $pagestr .= "<a href='?page=$i' style='text-decoration:none'>";
            if($i==$page)$pagestr .= "<span style='color:red;font-weight:bold'>[";
            $pagestr .= "$i";
            if($i==$page)$pagestr .= "</span>]";
            $pagestr .= "</a> ";          
        }
        $query = $db->query("SELECT * FROM book order by number desc limit $startlimit, $pageview");
        $results = $query->getResultArray();
        $data = [
            'title'=>"도서 목록",
            'booklist'=>$results,
            'pagestr'=>$pagestr
        ];
        return view('booklist2', $data);
    }
}

CodeIgniter4\App\Views\booklist2.php

<style>
    .title_style { font-size:12pt; color:blue}
    .author_style { font-size:9pt; color:gray}
</style>
<u><b><?=$title?></b></u><br/>
<?=$pagestr?><br/>
<hr/>
<? foreach ($booklist as $book){?>
<span class=title_style><?= $book['title']?></span>
<span class=author_style>/ <?= $book['author']?></span>
<span class=author_style>/ <a href="bookEdit?number=<?= $book['number']?>">[편집]</a></span>
<span class=author_style>/ <a href="bookDelete?number=<?= $book['number']?>">[삭제]</a></span>
<br/>
<? } ?>
<hr/>
<?=$pagestr?><br/>

이제 아래 URL 로 접속하시면, 책목록이 20개씩 나열됩니다.
책이 총 140권이 있고 7개의 페이지로 구성되었군요?

http://localhost:8080/bookList2

그리고 페이지 번호를 클릭하면 20개씩 끊어서 각 페이지에 대항하는 책 목록이 보이실 겁니다.

책목록을 제공하는 컨트롤러 소스가 약간 복잡해졌습니다.
주요 변경된 부분은 아래와 같은데요.

        $pageview=20; 
        $page=$this->request->getVar("page"); 
        if($page=="")$page=1; 
        $startlimit=($page-1)*$pageview; 
        $query_count = $db->query("SELECT count(*) FROM book"); 
        $results_count = $query_count->getResultArray(); 
        $total = $results_count[0]['count(*)']; 
        $totalpage = ceil($total / $pageview); 
        $pagestr="{$total}건, {$totalpage}페이지 / "; 
        for($i=1;$i<=$totalpage;++$i){
            $pagestr .= "<a href='?page=$i' style='text-decoration:none'>";
            if($i==$page)$pagestr .= "<span style='color:red;font-weight:bold'>[";
            $pagestr .= "$i";
            if($i==$page)$pagestr .= "</span>]";
            $pagestr .= "</a> ";          
        }
        $query = $db->query("SELECT * FROM book order by number desc limit $startlimit, $pageview"); 

페이지 기능을 구현하는 방법은 여러가지가 있겠지만,
크레이가 주로 사용하는 방법을 소개해 드리겠습니다.
꼭 이 방법이 정답은 아닙니다 :)
아주 여러가지 방법으로 구현이 가능하니까요.

우선 개념적인 설명을 드리겠습니다.
페이지를 만들기 위해 필요한 사전 정의는 무엇이 있을까요?

1) 페이지당 게시글 수
먼저 페이지에 몇개의 게시글을 보여줄 것인가에 대한 정의가 필요합니다.

2) 게시글의 순서
전체 게시글을 보여드릴 때는 그다지 신경쓰지 않았지만 페이지 목록을 보여줄 때는 매우 중요합니다.
게시글을 어떤 순서로 보여줄 것인가에 대한 정의가 필요합니다.

3) 현재 페이지
이 요소는 페이지 번호를 클릭했을 때, 현재 보여줄 몇번째 페이지에 대한 값을 담고 있어야 합니다.

4) 게시물시작위치 공식
게시글의 시작 위치에 대한 공식은 아래와 같습니다.
참고로 MySQL 컴퓨터에서 게시글 최초의 순서는 0부터 시작됩니다.

(현재페이지-1) * 페이지당 게시글 수

만일 1페이지라면 ( 1 - 1 ) * 20 = 0 이기 때문에 0번째 게시물부터 보여주기를 시작하고,
7페이지라면 ( 7 - 1 ) * 20 = 120 이기 때문에 120번째 게시물부터 보여주기를 시작합니다.

5) 총 페이지 갯수 공식
총 페이지 갯수를 산출하는 공식은 아래와 같습니다.

총게시글수 / 페이지당 게시글 수 => 소숫점 올림 처리

만일 게시글이 21개이고 페이지당 게시글 수가 20개라면
아래와 같이 계산됩니다.

21 / 20 = 1.05 올림처리=> 2 

그래서 총 페이지는 2페이지가 됩니다.

여기까지가 페이징 기능 구현의 기본적인 개념인데요.
코드를 한줄씩 살펴보도록 하겠습니다. 지난 번과 중복된 부분은 제외하구요,

먼저 아래 코드는 한 페이지에 몇개의 게시글을 보여줄 것인지 사전 정의합니다.
만일 이 값을 변경해주시면 한 페이지에 보여지는 게시글의 갯수가 변경되지요.

        $pageview=20;  

이어서 아래 코드가 보이는데요.
맨 처음 bookList2 페이지에 접속한 경우 이 값은 아무 의미가 없기 때문에,
$page 변수에 공백문자열 값이 입력됩니다.
그러니 우선 공백문자열로 가정하고 이 코드는 후반부에 다시 설명드리도록 하겠습니다.

        $page=$this->request->getVar("page");  

이어서 아래 코드가 실행되지요.
$page 변수값이 공백일 경우 1을 대입합니다. 당연히 1이 대입되겠지요? 이는 1페이지를 의미합니다.

        if($page=="")$page=1;  

이제 아래 코드는 게시글 공식을 이용, 게시글의 시작위치를 산출합니다.
$page 값이 1, 즉 1페이지이니까 (1-1)*20 = 0이 됩니다.
즉 게시글의 시작 위치는 0입니다.

        $startlimit=($page-1)*$pageview;  

이어서 총 페이지 갯수를 구하기 위해, 우선 총 게시물 갯수를 구하는 코드가 실행됩니다.

        $query_count = $db->query("SELECT count(*) FROM book");  
        $results_count = $query_count->getResultArray();  
        $total = $results_count[0]['count(*)'];  

위 코드에서 다음과 같은 SQL 명령문이 실행이 되는데요,
count(*) 의 경우 속도가 매우 빠르기 때문에 자주 애용되는 기술입니다.

SELECT count(*) FROM 테이블명

그리고 총 페이지를 구하는 공식에 의해 총 몇페이지까지 존재하는지를 산출화는 코드가 이어집니다.
ceil 함수는 소숫점 결과를 올림하는데, $totalpage 변수에 총 페이지수가 대입됩니다.

        $totalpage = ceil($total / $pageview);  

다음으로 각 페이지로 연결하는 링크와 현재 페이지 위치를 빨간색으로 보여주기 위해 HTML 태그를 만들어서 변수에 저장합니다.

        $pagestr="{$total}건, {$totalpage}페이지 / ";  
        for($i=1;$i<=$totalpage;++$i){
            $pagestr .= "<a href='?page=$i' style='text-decoration:none'>";
            if($i==$page)$pagestr .= "<span style='color:red;font-weight:bold'>[";
            $pagestr .= "$i";
            if($i==$page)$pagestr .= "</span>]";
            $pagestr .= "</a> ";          
        }

이 코드는 아래와 같이 페이지 게시글 수, 총 페이지, 페이지 목록과 현재 페이지를 보여주는 HTML 태그를 $pagestr 변수에 보관하지요. 그 값은 아래와 같이 보관됩니다.

140건, 7페이지 / 
<a href='?page=1' style='text-decoration:none'><span style='color:red;font-weight:bold'>[1]</span></a>
<a href='?page=2' style='text-decoration:none'>2</span></a>
<a href='?page=3' style='text-decoration:none'>3</span></a>
<a href='?page=4' style='text-decoration:none'>4</span></a>
       :

이는 나중에 뷰에서 절적한 위치에 이렇게 표시될 예정입니다.

그리고 $query 부분 또한 게시글 시작 순번으로부터 20개까지만 게시글을 받아오기 위해,
아래 모양으로 코드가 변경되었습니다. 

        $query = $db->query("SELECT * FROM book order by number desc limit $startlimit, $pageview"); 

1페이지인 경우 $startlimit 값이 0입니다. $pagelimit 값은 항상 20이기 때문에.
SQL 문장은 아래와 같이 해석됩니다.

SELECT * FROM book order by number desc limit 0, 20

위 SQL 명령은 게시물에 매겨진 일련번호 number 의 역순으로 게시물 순번 0번부터 20개의 게시물을 뽑아내라는 명령이 되지요.

그렇게 때문에 20개까지만 게시물이 나열됩니다.
그 아랫 부분의 소스는 이전의 책목록과 다른 부분은 없으며 마지막에 $pagestr 을 넘겨주는 부분과
뷰로 연결하는 부분만 booklist2.php 로 바뀌었습니다.

        $data = [
            'title'=>"도서 목록",
            'booklist'=>$results,
            'pagestr'=>$pagestr
        ];
        return view('booklist2', $data);

이제 뷰로 넘어가도록 하겠습니다.
뷰에서는 사실 변경된 부분이 두 곳밖에 없습니다.
바로 아래와 같은 부분인데요.
이는 컨트롤러에서 만들었던 페이지 목록 $pagestr 변수를 그대로 표시해주는 부분입니다.

<?=$pagestr?><br/>
<hr/>
<hr/>
<?=$pagestr?><br/>

화면의 위쪽과 아래쪽에 페이지 정보을 보여줌으로서 현재 어디에 위치해 있는지를 쉽게 나타낼 수 있고,

페이지 클릭시 해당 페이지로 이동하게 하기 위함입니다.
페이지 목록에서 4를 클릭할 경우 무슨 일이 일어날까요?
이 태그는 아래와 같이 때문에,

<a href='?page=4' style='text-decoration:none'>4</span></a>

"?page=4" 페이지로 링크됩니다. "?" 기호 앞이 생략되면 현재 페이지라는 의미이기 때문에 BookList2 페이지로 이동하며 아울러 GET 항목으로 page 변수에 4값을 담아서 이동됩니다.

이제 좀 전에 설명드리지 않았던 코드를 확인해보도록 할까요?
페이지에 처음 접속하는 경우가 아니라, 4페이지를 클릭해서 진입하는 경우
아래 소스 코드의 결과는 공백값이 아니라 "4"가 됩니다.
그래서 4값이 $page 변수에 대입이 됩니다.

        $page=$this->request->getVar("page");  

그리고 이번에는 $page 값이 공백이 아니기 때문에, 아래 코드에서 $page 값이 바뀌지 않게 되지요.

        if($page=="")$page=1;  

이 경우 게시물 시작 공식 계산식에서도 아래 소스에 의해 80이란 값이 산출되어 $startlimit  변수에 값이 대입되어,
결국 게시글의 80번째 글부터 받아오는 것입니다.

        $startlimit=($page-1)*$pageview;  

코드이그나이터에서 만나보는 페이징 기능,
처음 페이징 기능을 접하는 경우 꽤 혼동하도록 되어 있는데
어느정도 감이 오시는지 모르겠습니다.
반복할수록 익숙해지니 처음에 너무 어렵다고 좌절하거나 하시진 마세요 :)

이해가 어려운 부분 있으시면 댓글로 문의주시면 힘닿는데로 답변드리도록 하겠습니다.
아무쪼록 도전하시는 분들께 화이팅입니다 :)

오늘도 여기까지 읽어주신 분들께 감사드립니다.

  • BlogIcon 맛집찾아주는남자 2020.05.03 08:14 신고

    .티스토리 여러주제의 글들을 서칭하다가 썸네일을 잘쓰셔서 들어왔어요. 글을 처음부터 끝까지 다 읽었는데 굉장히 글을 잘쓰시는것같아요. 어떻게 하면 그리 글을 잘쓸수있을까요? 저도 맛집탐방을 주제로 하고는 있지만 아직 부족한점이 많은것같습니다. 시간되실때 들어오셔서 문제점을 지적해시면 개선하겠습니다!편안한 하루 보내세요!

    • BlogIcon Dr. CrayFall 2020.06.14 17:04 신고

      저도 많이 부족한데, 과찬이십니다 :)
      크레이는 파워블로거보다는 파워개발자를 지향합니다.

      개발자는 개발자를 알아본다고 이 블로그는 늘 저를 입증하는 포트폴리오인 셈이지요 :)