소개
페이지네이션은 데이터 기반 애플리케이션을 구축할 때 중요한 개념입니다. 데이터베이스에서 레코드를 가져올 때 방대한 양의 레코드가 조회될 수 있습니다. 예를 들어, 활성 사용자나 특정 지역에 속한 사용자를 조회하는 쿼리를 실행할 때 수백 또는 수천 명에 달하는 많은 사용자가 반환될 수 있습니다. 이처럼 방대한 양의 레코드를 단일 웹 페이지에 표시하는 것은 사용자에게 부담을 줄 뿐만 아니라 원활한 사용자 경험을 해칠 수 있으므로 사용자 친화적인 해결책이 아닙니다.
따라서 레코드 수를 제한하는 것이 더 바람직한 방법입니다. 이것이 바로 페이지네이션의 개념입니다. 다시 말해, 레코드 수를 여러 페이지로 나누어 표시하는 것입니다. 단일 페이지에는 프론트엔드에 표시하기 적절한 10개, 15개 또는 기타 적당한 수의 레코드를 담을 수 있습니다.
페이지네이션은 애플리케이션의 전반적인 사용자 경험을 향상시킬 뿐만 아니라, 가져오는 레코드 수를 줄여주기 때문에 애플리케이션의 속도도 빨라지게 합니다. 결과적으로 클라이언트와 서버 간의 네트워크를 통해 전송되는 데이터가 줄어들어 대기 시간이 단축됩니다.
이 튜토리얼에서는 데이터베이스에 연결하는 PHP 코드를 작성하고, MySQL 데이터베이스와 해당 데이터베이스의 LIMIT 절을 사용하여 페이지네이션을 구현해 보겠습니다..
사전 요구 사항
이 튜토리얼을 진행하려면 다음이 필요합니다.
-
최신 버전의 Ubuntu가 설치되어 실행 중이어야 합니다. 도움이 필요하다면 Ubuntu 서버 설정 방법 튜토리얼을 참고하세요.
-
또한 PHP와 MySQL이 설치되어 있어야 합니다. PHP 및 MySQL을 설정하려면 다음 튜토리얼을 참고하세요: LAMP 스택 설정 – Linux Apache MySQL PHP.
1단계 — 데이터베이스 사용자 및 테스트 데이터베이스 설정
이 튜토리얼에서는 MySQL 데이터베이스와의 연결을 설정하고 레코드를 가져옵니다. 이 레코드들은 테이블 요소를 사용하여 HTML 페이지에 표시됩니다. 연결을 설정하고 레코드를 표시하기 위해 PHP 스크립트를 사용할 것입니다. 데이터베이스 연결이 준비되면 페이지네이션이 있는 경우와 없는 경우로 애플리케이션을 테스트해 보겠습니다. 이렇게 테스트하면 페이지네이션이 실제로 어떻게 작동하는지 이해하는 데 도움이 됩니다.
MySQL 데이터베이스에 연결하려면 샘플 MySQL 데이터베이스와 데이터베이스에 연결할 사용자의 인증 정보가 필요합니다. 이 단계에서는 PHP 스크립트를 테스트하기 위해 MySQL 데이터베이스용 non-root 사용자, 샘플 데이터베이스 및 테이블을 생성합니다.
먼저 서버에 로그인합니다. 그런 다음 아래 명령어를 사용하여 MySQL 서버에 로그인합니다.
|
1 |
mysql> sudo mysql -u root -p |
root 사용자의 비밀번호를 입력하라는 메시지가 표시됩니다. 비밀번호를 입력하고 Enter 키를 눌러 진행합니다. 다음으로, 이 튜토리얼에서 사용할 test_db라는 이름의 샘플 데이터베이스를 생성합니다. 새 데이터베이스를 생성하려면 아래 명령어를 실행하세요:
|
1 |
mysql> Create database test_db; |
MySQL 서버에서 한 행이 영향을 받았다는 출력이 표시됩니다. 다음으로, 이 데이터베이스를 위한 새 사용자를 생성해야 합니다. 이 사용자에게 모든 권한을 부여할 것입니다. 하지만 실제 애플리케이션을 작업할 때는 권한을 제한해야 합니다. 이 사용자의 이름을 test_user(으)로 지정하겠습니다. 아래 명령어에서 PASSWORD 부분을 강력한 비밀번호로 변경하세요:
|
1 |
mysql> GRANT ALL PRIVILEGES ON test_db.* TO 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD'; |
사용자가 생성되면 권한을 플러시(적용)합니다.
|
1 |
mysql> FLUSH PRIVILEGES; |
이제 test_user와 test_db가 모두 준비되었으므로, test_db를 사용하여 테이블을 생성합니다. test_db(으)로 전환하려면 아래 명령어를 실행하세요:
|
1 |
mysql> Use test_db; |
출력에서 데이터베이스가 변경된 것을 확인하면 테이블을 생성할 준비가 된 것입니다. 제품 정보를 담을 Products라는 이름의 새 테이블을 생성하겠습니다. 이 튜토리얼에서는 이 테이블에 product_id 및 product_name의 두 개 열만 필요합니다. product_id를 AUTO_INCREMENT, 새로운 제품을 추가할 때마다 값이 증가하도록 합니다. 다른 열인 product_name 은(는) 제품의 이름을 저장하는 데 사용됩니다. product_name 열은 각 제품을 이름으로 구분하는 데 사용됩니다:
|
1 |
mysql> Create table products (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50) NOT NULL ) Engine = InnoDB; |
이제 몇 가지 products을(를) 이 새로 생성된 테이블에 추가하겠습니다. 이를 위해 아래 명령어를 실행하세요:
|
1 2 3 4 5 6 7 8 9 10 |
mysql> Insert into products(product_name) values ('WIRELESS MOUSE'); mysql> Insert into products(product_name) values ('BLUETOOTH SPEAKER'); mysql> Insert into products(product_name) values ('GAMING KEYBOARD'); mysql> Insert into products(product_name) values ('320GB FAST SSD'); mysql> Insert into products(product_name) values ('17 INCHES TFT'); mysql> Insert into products(product_name) values ('SPECIAL HEADPHONES'); mysql> Insert into products(product_name) values ('HD GRAPHIC CARD'); mysql> Insert into products(product_name) values ('80MM THERMAL PRINTER'); mysql> Insert into products(product_name) values ('HDMI TO VGA CONVERTER'); mysql> Insert into products(product_name) values ('FINGERPRINT SCANNER'); |
이 제품들이 테이블에 입력되었는지 확인하려면 아래 명령어를 실행하세요:
|
1 |
mysql> select * from products; |
위에서 입력한 제품들이 보인다면 다음 단계로 진행할 준비가 된 것입니다. 아래 명령어를 사용하여 MySQL 데이터베이스를 종료하세요:
|
1 |
mysql> quit; |
이제 MySQL 데이터베이스를 설정하고 테스트 데이터를 입력했으므로, 이 데이터베이스에 연결하여 레코드를 가져오는 PHP 스크립트를 작성할 준비가 되었습니다.
2단계 – 페이지네이션 없이 레코드 가져오기 및 표시하기
위에서 논의한 바와 같이, 먼저 페이지네이션 없이 레코드를 표시하겠습니다. MySQL 데이터베이스에 연결하여 레코드를 가져오는 PHP 스크립트를 빌드할 것입니다. 위에서 생성한 test_db에 test_user을(를) 사용하여 연결하고 레코드를 가져옵니다.
현재 products 테이블에는 현재 10개의 레코드만 있습니다. 많은 사용자에게 페이지네이션이 필요한지 여부가 명확하지 않을 수 있습니다. 하지만 페이지네이션 없이 애플리케이션을 테스트해 보면 이것이 애플리케이션의 전반적인 경험에 어떻게 도움이 되는지 자세히 알 수 있습니다. 또한 데이터를 분할하는 것이 어떻게 더 나은 사용자 경험을 제공하고 서버의 부담을 줄이는지 이해하게 될 것입니다.
PHP 서버의 웹사이트 폴더 루트 디렉터리(document root)에서 아래 명령어를 실행하세요:
sudo nano /var/www/html/pagination_test.php
이제 이 파일에 아래 내용을 추가합니다. PASSWORD 부분을 귀하의 test_user:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php try { $pdo = new PDO("mysql:host=localhost;dbname=test_db", "test_user", "PASSWORD"); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); $sql = "select * from products"; $stmt = $pdo->prepare($sql); $stmt -> execute(); echo "<table border='1' align='center'>"; while (($row = $stmt -> fetch(PDO::FETCH_ASSOC)) !== false) { echo "<tr>"; echo "<td>".$row['product_id']."</td>"; echo "<td>".$row['product_name']."</td>"; echo "</tr>"; } echo "</table>"; } catch(PDOException $e) { echo $e->getMessage(); } ?> |
파일을 저장합니다. 계속 진행하기 전에 위에서 수행한 작업을 요약해 보겠습니다:
-
먼저 MySQL 데이터베이스에 연결했으며, 이를 위해 PHP Data Object (PDO) 라이브러리를 사용했습니다. 위에서 사용한 MySQL 사용자의 자격 증명을 사용하여 MySQL 데이터베이스에 연결했습니다. PDO는 데이터베이스 연결에 사용되는 매우 유용한 라이브러리입니다. 데이터 액세스 계층을 쉽게 코딩할 수 있게 해주고, 애플리케이션을 대대적으로 리팩터링하지 않고도 다양한 데이터베이스에 연결할 수 있도록 지원합니다. PDO는 준비된 문(prepared statements)을 사용하여 보안이 손상되지 않도록 보장합니다. 따라서 쿼리가 안전하게 실행됩니다.
-
다음으로, PDO API를 사용하여 select * from products 문을 실행했습니다. $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false)는 PHP의 데이터 타입이 데이터베이스의 데이터 타입과 동일하도록 보장합니다. 따라서 product_id 및 product_name은 각각 정수와 문자열로 나타납니다.
-
The $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);은 오류가 발생할 경우 PDO가 예외를 발생시키도록 지시합니다. 이렇게 함으로써 try … catch 블록에서 예외를 쉽게 포착하고 필요에 따라 처리할 수 있습니다.
이제 스크립트가 준비되었으므로 이를 실행해야 합니다. 이를 위해 브라우저를 열고 다음 URL로 이동합니다: /var/www/html/pagination_test.php. URL 뒤에 서버 IP를 추가해야 합니다. 로컬에서 실행 중인 경우 URL은 다음과 같이 됩니다: http://localhost/var/www/html/pagination_test.php.
아래와 같은 출력이 표시됩니다:

여기서 제품이 반환되어 페이지에 표시됩니다. 이제 수백 개의 제품이 있다고 가정해 보겠습니다. 데이터를 가져와 페이지에 표시하는 데 긴 루프가 발생할 것입니다. 이는 페이지 로딩 시간을 증가시킵니다.
다음 섹션에서는 PHP 스크립트를 수정하고 MySQL LIMIT 절을 포함할 것입니다. 이렇게 하면 많은 수의 레코드를 표시하는 문제가 해결됩니다. 사용자가 페이지를 탐색할 수 있도록 페이지네이션 링크를 추가할 것입니다.
3단계 – PHP를 사용하여 페이지네이션 설정하기
이 단계에서는 여러 테이블을 사용하여 데이터를 표시하기 위해 PHP를 사용하여 페이지네이션을 설정합니다. 페이지네이션을 적용하기 위해 이전 단계에서 코딩한 스크립트를 수정할 것입니다.
우리는 MySQL 데이터베이스의 LIMIT 절을 사용할 것입니다. 이를 스크립트에 추가하기 전에 MySQL LIMIT 구문의 예를 살펴보겠습니다.
|
1 |
mysql> Select [column1, column2, column n...] from [table name] LIMIT offset, records; |
위의 문장에서 우리는 LIMIT 절이 offset 및 records 인수를 가지고 있음을 알 수 있습니다. offset은 건너뛸 레코드 수를 알려주고 records는 페이지당 표시하거나 데이터베이스에서 가져올 최대 레코드 수를 알려줍니다.
이제 페이지네이션이 어떻게 작동하는지 알았으므로 이를 구현하는 방법을 살펴보겠습니다. 페이지당 3개의 레코드를 표시할 것입니다. 따라서 데이터베이스에 10개의 레코드가 있는 경우 전체 레코드 수를 페이지당 레코드 수로 나누어 4개의 페이지를 갖게 됩니다. 결과가 정수가 아닐 수 있으므로, PHP의 Ceil 함수를 사용하여 가장 가까운 정수로 올림하여 정수 결과를 얻을 것입니다. 다음은 Ceil 함수를 보여주는 간단한 코드 스니펫입니다:
|
1 |
$total_pages=ceil($total_records/$per_page); |
이제 페이지네이션 코드를 추가하겠습니다. 페이지네이션을 활성화하고 탐색 링크를 추가하려면 아래 명령을 사용하여 /var/www/html/pagination_test.php 파일을 여십시오:
|
1 |
$ sudo nano /var/www/html/pagination_test.php |
다음으로, 이 파일의 내용을 아래 코드로 바꿉니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<?php try { $pdo = new PDO("mysql:host=localhost;dbname=test_db", "test_user", "PASSWORD"); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); /* 페이징 정보 시작 */ $page = 1; if (isset($_GET['page'])) { $page = filter_var($_GET['page'], FILTER_SANITIZE_NUMBER_INT); } $per_page = 3; $sqlcount = "select count(*) as total_records from products"; $stmt = $pdo->prepare($sqlcount); $stmt->execute(); $row = $stmt->fetch(); $total_records = $row['total_records']; $total_pages = ceil($total_records / $per_page); $offset = ($page-1) * $per_page; /* 페이징 정보 끝 */ $sql = "select * from products limit :offset, :per_page"; $stmt = $pdo->prepare($sql); $stmt->execute(['offset'=>$offset, 'per_page'=>$per_page]); echo "<table border='1' align='center'>"; while ( ($row = $stmt->fetch(PDO::FETCH_ASSOC) ) !== false) { echo "<tr>"; echo "<td>".$row['product_id']."</td>"; echo "<td>".$row['product_name']."</td>"; echo "</tr>"; } echo "</table>"; /* 네비게이션 시작 */ echo "<table border='1' align='center'>"; echo "<tr>"; if ($page-1 >= 1) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page - 1).">이전</a></td>"; } if ($page+1 <= $total_pages) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page + 1).">다음</a></td>"; } echo "</tr>"; echo "</table>"; /* 네비게이션 끝 */ } catch(PDOException $e) { echo $e->getMessage(); } ?> |
이 코드의 요약은 다음과 같습니다:
-
현재 머물고 있는 페이지에 대한 정보를 유지해야 합니다. 이를 위해 $page 변수를 사용합니다. $page 변수는 $_GET[‘page’] 변수를 사용하여 현재 머물고 있는 페이지를 추출하는 데 사용됩니다.
-
다음으로, 한 페이지에 표시할 페이지 수를 지정해야 합니다. 이를 위해 $per_page 변수입니다. 여기서는 페이지당 세 개의 상품만 표시하고 있습니다.
-
위에서 언급했듯이, 데이터베이스에 존재하는 총 레코드 수가 필요합니다. 이는 총 페이지 수를 식별하기 위해 필요합니다. $total_records 변수가 이 정보를 보유합니다.
-
마지막으로, 건너뛸 레코드 수를 알아야 합니다. 예를 들어, 두 번째 페이지에 있는 경우 데이터베이스의 처음 세 개 레코드를 건너뛰어야 합니다. 우리는 $offset 변수를 사용하여 이 정보를 보유합니다. 우리는 페이지를 로드할 때마다 다음 공식을 사용하여 이 정보를 계산했습니다. $offset=($page-1)*$per_page. 다른 개수의 항목을 표시해야 하는 경우, $per_page 변수에 값을 지정할 수 있습니다.
-
탐색 버튼을 표시하기 위해 아래 코드를 사용합니다:
|
1 2 3 4 5 6 7 8 9 10 |
. . . if( $page-1>=1) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page-1).">이전</a></td>"; } if( $page+1<=$total_pages) { echo "<td><a href=".$_SERVER['PHP_SELF']."?page=".($page+1).">다음</a></td>"; } . . . |
로직은 $page가 현재 페이지를 유지하는 데 사용된다는 것입니다. 페이지에 이전 옵션을 표시하려면 스크립트가 $page 변수 값에서 1을 뺍니다. 결과가 1보다 크거나 같으면 페이지에 이전 옵션이 표시됩니다.
마찬가지로, 다음 옵션을 표시하려면 $page 변수에 1을 더합니다. 여기서 우리는 더한 결과가 $total_pages 변수의 총 페이지 수를 초과하지 않도록 합니다.
그 후, 페이지를 확인할 차례입니다. 브라우저를 열고 이전에 사용한 URL을 사용하여 해당 페이지로 이동합니다:
|
1 |
http://your_server_ip/pagination_test.php |
아래와 같은 출력을 보게 될 것입니다:



여기서 여러분은 마침내 PHP 스크립트에서 MySQL의 LIMIT 절을 사용하여 페이지네이션을 구현했습니다. 애플리케이션에 페이지네이션을 구현하면 여러 레코드를 탐색하는 더 나은 방법을 갖게 됩니다.
결론
이 튜토리얼에서는 Ubuntu에서 PHP와 MySQL을 사용하여 페이지네이션을 구현하는 방법을 살펴보았습니다. 이 단계들을 활용하여 효과적인 조작을 위해 페이지별로 나누어 대량의 레코드를 적절하게 표시할 수 있는 애플리케이션을 구축할 수 있습니다.
또한, Ubuntu에서 PHP 및 MySQL을 사용하는 데 도움이 되는 더 많은 튜토리얼이 있습니다:
- Ubuntu 18.04에서 phpMyAdmin 설치 및 보안 설정하기
- MariaDB 또는 MySQL Root 비밀번호 재설정 방법
- CloudSigma 튜토리얼: 서버에 MySQL을 설정하는 방법 및 MySQL 기본 사항
즐거운 컴퓨팅 되세요!
댓글
아직 댓글이 없습니다. 첫 번째로 작성해 보세요.