در این آموزش PHP قصد داریم به شما نحوه ساخت صفحه بندی با PHP و Mysql همانند گوگل را نشان بدیم.
در آموزش های قبلی ارایه شده توسط نت پارادیس نحوه ساخت انواع صفحه بندی (pagination) را نشان دادیم :
ولی در این آموزش نحوه ساخت صفحه بندی با PHP بصورت ساده و بدون استفاده از Ajax را یاد بدیم.
در این آموزش٬ دو نوع کنترل برای پیمایش نتایج صفحه بنده شده داریم.
اولی٬ لینک های صفحه بندی برای هدایت ما به صفحه مدنظر و بعدی هم یک ورودی متن (input
) برای وارد کردن شماره صفحه است. با سابمیت کردن این شماره صفحه٬ می توانیم به صفحه مورد نظر بریم.
من مثال آموزش ساخت صفحه بندی با PHP و Mysql همانند گوگل را با یک مثال ساده پیاده سازی کردم. که البته همین مثال را بصورت ajax در مقالات قبلی دیدیم.
من صفحه بندی را برای لیست نتایج دیتابیس از نام حیوانات طراحی کردم. تعداد لینک ها بر اساس تعداد رکوردهای جدول animal تغییر می کند.
تعداد نمایش نتایج در هر صفحه نیز از طریق یک ثابت در کلاس Config
قابل تنظیم است.
پلاگین ها برای فعال کردن قابلیت صفحه بندی (pagination)
پلاگین های زیادی برای ساخت سریع صفحه بندی وجود دارند که از بین آنها Pagination.js و jqPaginator بسیار کاربردی و در عین حال سبک هستند.
Datatables یکی از محبوب ترین کتابخانه هایی است که برای مدیریت جداول داده ای استفاده می شود. این کتابخانه دارای جستجو٬ صفحه بندی٬ ترتیب بندی و دیگر قابلیت ها است.
در یک مقاله قبلی نحوه پیاده کردن Datatables برای لیست کردن رکوردها با صفحه بندی را دیدیم.
با گفتن همه این ها٬ بهتر است کد سفارشی خودمان را بنویسیم. چراکه پلاگین و کتابخانه های خارجی فقط اپلیکیشن ما را کند می کنند.
ساختار فایل ها
مثال ما شامل فایل ها زیر است :
فایل index.php همان صفحه اصلی HTML ما است که برای نمایش لینک های صفحه بندی و نتایج صفحه فعلی استفاده می شود.
دو فایل CSS نیز برای استایل دهی چیدمان صفحه ما در این مثال استفاده شده اند.
فایل Model/Pagination.php نیز شامل توابعی برای واکشی داده های Mysql است که پارامترهایی برای ست کردن limit
در کوئری SELECT
دریافت می کند.
ساختار فایل ما شامل یک اسکریپت SQL هم است که برای ساخت دیتابیس مثال ساخت صفحه بندی با PHP و Mysql استفاده می شود.
اسکریپت دیتابیس
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
-- -- Database: `pagination` -- -- -------------------------------------------------------- -- -- Table structure for table `tbl_animal` -- CREATE TABLE `tbl_animal` ( `id` int(11) UNSIGNED NOT NULL, `common_name` varchar(255) NOT NULL DEFAULT '', `scientific_name` varchar(255) NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- -- Dumping data for table `tbl_animal` -- INSERT INTO `tbl_animal` (`id`, `common_name`, `scientific_name`) VALUES (1, 'Bison', 'Bos gaurus\r\n'), (2, 'Black buck', 'Antelope cervicapra'), (3, 'Chinkara', 'Gazella bennettii'), (4, 'Nilgai', 'Boselaphus tragocamelus'), (5, 'Wolf', 'Canis lupus'), (6, 'Lion', 'Panthera leo'), (7, 'Elephant', 'Elephas maximus'), (8, 'Wild Ass', 'Equus africanus asinus'), (9, 'Panther', 'Panthera pardus'), (10, 'Kashmir stag', 'Cervus canadensis hanglu'), (11, 'Peacock', 'Pavo cristatus'), (12, 'Siberian crane', 'Grus leucogeranus'), (13, 'Fox', 'Vulpes vulpes'), (14, 'Rhinoceros', 'Rhinoceros unicornis'), (15, 'Tiger', 'Panthera Tigris'), (16, 'Crocodile', 'Crocodylus palustris'), (17, 'Gavial or Gharial', 'Gavialis gangeticus'), (18, 'Horse', 'Equus caballus'), (19, 'Zebra', 'Equus quagga'), (20, 'Buffalow', 'Babalus bubalis'), (21, 'Wild boar', 'Sus scrofa'), (22, 'Arabian camel', 'Camelus dromedaries'), (23, 'Giraffe', 'GiraffaÊcamelopardalis'), (24, 'House wall Lizard', 'Hemidactylus flaviviridis'), (25, 'Hippopotamus', 'Hippopotamus amphibius'), (26, 'Rhesus monkey', 'Macaca mulatta'), (27, 'Dog', 'Canis lupus familiaris'), (28, 'Cat', 'Felis domesticus'), (29, 'Cheetah', 'Acinonyx jubatus'), (30, 'Black rat', 'Rattus rattus'), (31, 'House mouse', 'Mus musculus'), (32, 'Rabbit', 'Oryctolagus cuniculus'), (33, 'Great horned owl', 'Bubo virginianus'), (34, 'House sparrow', 'Passer domesticus'), (35, 'House crow', 'Corvus splendens'), (36, 'Common myna', 'Acridotheres tristis'), (37, 'Indian parrot', 'Psittacula eupatria'), (38, 'Bulbul', 'Molpastes cafer'), (39, 'Koel', 'Eudynamis scolopaccus'), (40, 'Pigeon', 'Columba livia'), (41, 'Indian Cobra', 'Naja naja'), (42, 'King cobra', 'Ophiophagus hannah'), (43, 'Sea snake', 'Hydrophiinae'), (44, 'Indian python', 'Python molurus'), (45, 'Rat snake', 'Rat snake'); -- -- Indexes for dumped tables -- -- -- Indexes for table `tbl_animal` -- ALTER TABLE `tbl_animal` ADD PRIMARY KEY (`id`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `tbl_animal` -- ALTER TABLE `tbl_animal` MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=46; |
ساخت صفحه اصلی با دکمه های صفحه بندی
این لندینگ پیچ نتایج دیتابیس را با آپشن صفحه بندی را نمایش می دهد. کد HTML زیر شامل کدهای 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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
<!doctype html> <html lang="en"> <head> <title>PHP Pagination MySQL Database Example Script with Previous Next like Google</title> <link rel="stylesheet" type="text/css" href="assets/css/pagination.css"> <link rel="stylesheet" type="text/css" href="assets/css/phppot-style.css"> <script src="vendor/jquery/jquery-3.3.1.js"></script> </head> <body> <div class="phppot-container"> <div class="phppot-form"> <h1>Animal Names</h1> <table> <tr> <th>Id</th> <th>Common Name</th> <th>Scientific Name</th> </tr> <?php if (! empty($pageResult)) { foreach ($pageResult as $page) { ?> <tr> <td><?php echo $page['id'];?></td> <td><?php echo $page['common_name'];?></td> <td><?php echo $page['scientific_name'];?></td> </tr> <?php }} ?> </table> <div class="pagination"> <?php if (($page > 1) && ($pn > 1)) { ?> <a class="previous-page" id="prev-page" href="<?php echo $queryString;?>page=<?php echo (($pn-1));?>" title="Previous Page"><span>❮ Previous</span></a> <?php }?> <?php if (($pn - 1) > 1) { ?> <a href='index.php?page=1'><div class='page-a-link'> 1 </div></a> <div class='page-before-after'>...</div> <?php } for ($i = ($pn - 1); $i <= ($pn + 1); $i ++) { if ($i < 1) continue; if ($i > $totalPages) break; if ($i == $pn) { $class = "active"; } else { $class = "page-a-link"; } ?> <a href='index.php?page=<?php echo $i; ?>'> <div class='<?php echo $class; ?>'><?php echo $i; ?></div> </a> <?php } if (($totalPages - ($pn + 1)) >= 1) { ?> <div class='page-before-after'>...</div> <?php } if (($totalPages - ($pn + 1)) > 0) { if ($pn == $totalPages) { $class = "active"; } else { $class = "page-a-link"; } ?> <a href='index.php?page=<?php echo $totalPages; ?>'><div class='<?php echo $class; ?>'><?php echo $totalPages; ?></div></a> <?php } ?> <?php if (($page > 1) && ($pn < $totalPages)) { ?> <a class="next" id="next-page" href="<?php echo $queryString;?>page=<?php echo (($pn+1));?>" title="Next Page"><span>Next ❯</span></a> <?php } ?> </div> <div class="goto-page"> <form action="" method="GET" onsubmit="return pageValidation()"> <input type="submit" class="goto-button" value="Go to"> <input type="text" class="enter-page-no" name="page" min="1" id="page-no"> <input type="hidden" id="total-page" value="<?php echo $totalPages;?>"> </form> </div> </div> </div> </body> </html> |
تابع pageValidation()
یک متد جاواسکریپت برای تایید شماره صفحه وارد شده است.
اگر باکس ورودی شامل داده غیرمعتبر بود٬ مقدار false برگشت داده می شود. پس از سابمیت شدن و رفتن به صفحه بعدی جلوگیری می کند.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<script> function pageValidation() { var valid=true; var pageNo = $('#page-no').val(); var totalPage = $('#total-page').val(); if(pageNo == ""|| pageNo < 1 || !pageNo.match(/\d+/) || pageNo > parseInt(totalPage)){ $("#page-no").css("border-color","#ee0000").show(); valid=false; } return valid; } </script> |
استایل های زیر مربوط به فایل pagination.css هستند که CSS های جدول و المان های صفحه بندی را شامل می شود.
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
.pagination { display: inline-flex; } .pagination a { color: #505050; text-decoration: none; } .page-a-link { font-family: arial, verdana; font-size: 12px; border: 1px #afafaf solid; background-color: #fbfbfb; padding: 6px 12px 6px 12px; margin: 6px; text-decoration: none; border-radius: 3px; } .active { font-family: arial, verdana; font-size: 12px; padding: 8px 14px 6px 14px; margin: 3px; background-color: #404040; text-decoration: none; border-radius: 3px; margin: 6px; color: #FFF; } a.previous-page { margin: 10px 10px 10px 0px; } a.prev-next:hover { color: #03a9f4; } a.next { margin: 10px 0px 10px 10px; } input.enter-page-no { width: 42px !important; height: 28px !important; font-size: 12px; padding: 6px 12px 6px 12px !important; margin: 6px; border-radius: 3px !important; text-align: center !important; } input.goto-button { max-width: 80px; font-size: 12px; padding: 6px 12px 6px 12px !important; border: 1px solid #9a9a9a; border-radius: 3px !important; text-align: center !important; background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #dfdd99), color-stop(100%, #bcbd2b)); background: -webkit-linear-gradient(top, #dfdc99, #b8bd2b); border: 1px solid #97a031; box-shadow: inset 0px 1px 0px rgb(255, 255, 211), 0px 1px 4px rgba(199, 199, 199, 0.9); } .goto-page { float: right; } .page-before-after { font-weight: bold; padding-top: 12px; text-decoration: none; } |
کد Php دریافت نتایج صفحه بندی شده
این اسکریپت php برای خواندن نتایج دیتابیس و دریافت شماره رکورد٬ شماره صفحات استفاده شده است.
شماره صفحات بر اساس تعداد نتایج و مقدار LIMIT_PER_PAGE
تغییر می کند.
اگر صفحات زیاد بودند٬ این اسکریپت ما فقط صفحات لیمیت شده را همانند صفحه بندی گوگل نمایش میدهد. این قابلیت به ما کمک می کند که بلوک صفحه بندی بدرستی در قالب صفحه نمایش داده شود.
در پیمایش پی در پی صفحه٬ لینک های صفحه بندی بیشتری نمایان می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php require_once __DIR__ . '/Model/Pagination.php'; $paginationModel = new Pagination(); $pageResult = $paginationModel->getPage(); $queryString = "?"; if (isset($_GET["page"])) { $pn = $_GET["page"]; } else { $pn = 1; } $limit = Config::LIMIT_PER_PAGE; $totalRecords = $paginationModel->getAllRecords(); $totalPages = ceil($totalRecords / $limit); ?> |
کلاس ها٬ کتابخانه ها و کانفیگ های استفاده شده
این یک کتابخانه معمولی استفاده شده در بیشتر پروژه های ما است و اینجا فقط توابع استفاده شده در این مثال را نشان دادیم.
برای دریافت کد کامل می توانید از باکس دانلود٬ سورس اضافه شده به آموزش ساخت صفحه بندی با PHP و Mysql همانند گوگل را دریافت کنید.
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
<?php /** * Copyright (C) 2019 NETPARADIS * * Distributed under MIT license with an exception that, * you don’t have to include the full MIT License in your code. * In essense, you can use it on commercial software, modify and distribute free. * Though not mandatory, you are requested to attribute this URL in your code or website. */ /** * Generic datasource class for handling DB operations. * Uses MySqli and PreparedStatements. * * @version 2.5 - recordCount function added */ class DataSource { // PHP 7.1.0 visibility modifiers are allowed for class constants. // when using above 7.1.0, declare the below constants as private const HOST = 'localhost'; const USERNAME = 'root'; const PASSWORD = 'test'; const DATABASENAME = 'pagination'; private $conn; /** * PHP implicitly takes care of cleanup for default connection types. * So no need to worry about closing the connection. * * Singletons not required in PHP as there is no * concept of shared memory. * Every object lives only for a request. * * Keeping things simple and that works! */ function __construct() { $this->conn = $this->getConnection(); } /** * If connection object is needed use this method and get access to it. * Otherwise, use the below methods for insert / update / etc. * * @return \mysqli */ public function getConnection() { $conn = new \mysqli(self::HOST, self::USERNAME, self::PASSWORD, self::DATABASENAME); if (mysqli_connect_errno()) { trigger_error("Problem with connecting to database."); } $conn->set_charset("utf8"); return $conn; } /** * To get database results * * @param string $query * @param string $paramType * @param array $paramArray * @return array */ public function select($query, $paramType = "", $paramArray = array()) { $stmt = $this->conn->prepare($query); if (! empty($paramType) && ! empty($paramArray)) { $this->bindQueryParams($stmt, $paramType, $paramArray); } $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows > 0) { while ($row = $result->fetch_assoc()) { $resultset[] = $row; } } if (! empty($resultset)) { return $resultset; } } /** * To insert * * @param string $query * @param string $paramType * @param array $paramArray * @return int */ public function insert($query, $paramType, $paramArray) { //... } /** * To execute query * * @param string $query * @param string $paramType * @param array $paramArray */ public function execute($query, $paramType = "", $paramArray = array()) { //... } /** * 1. * Prepares parameter binding * 2. Bind prameters to the sql statement * * @param string $stmt * @param string $paramType * @param array $paramArray */ public function bindQueryParams($stmt, $paramType, $paramArray = array()) { $paramValueReference[] = & $paramType; for ($i = 0; $i < count($paramArray); $i ++) { $paramValueReference[] = & $paramArray[$i]; } call_user_func_array(array( $stmt, 'bind_param' ), $paramValueReference); } /** * To get database results * * @param string $query * @param string $paramType * @param array $paramArray * @return array */ public function getRecordCount($query, $paramType = "", $paramArray = array()) { $stmt = $this->conn->prepare($query); if (! empty($paramType) && ! empty($paramArray)) { $this->bindQueryParams($stmt, $paramType, $paramArray); } $stmt->execute(); $stmt->store_result(); $recordCount = $stmt->num_rows; return $recordCount; } } |
فایل Config.php
ما محدودیت نمایش رکورد ها در هر صفحه را بصورت یک ثابت (constant) ذخیره کردیم که برای ست کردن limit
در کوئری SELECT
از آن استفاده می کنیم.
شما می توانید ثابت های بیشتری برای کار با اسکریپت صفحه بندی با PHP را اینجا اضافه کنید.
برای مثال٬ می توانید یک ثابت SHOW_ALL_LINKS
برای فعال/غیرفعال کردن محدودیت نمایش لینک ها اضافه کنید یا اینکه اطلاعات دیتابیس را اینجا تعریف و در کلاس بالا استفاده کنید.
1 2 3 4 5 6 7 |
<?php class Config { const LIMIT_PER_PAGE = '5'; } |
خروجی آموزش ساخت صفحه بندی با PHP و Mysql همانند گوگل
اسکرین شات زیر خروجی مثال ساخت صفحه بندی با PHP و Mysql را نشان می دهد.که همانطور که می بینید در هر صفحه ۵ رکورد را چاپ می کنیم.
در سمت چپ٬ لینک های صفحه قبلی و بعدی قرار گرفتند و در سمت راست یک فرم HTML برای وارد کردن شماره صفحه ایجاد کردیم.
امیدوارم از آموزش ساخت صفحه بندی با PHP و Mysql همانند گوگل نهایت استفاده را برده باشید.
برای دانلود سورس کد و دیتابیس از باکس دانلود استفاده کنید.
هر سوالی داشتید ، از قسمت نظرات ارسال کنید . سریعا ، پاسخگوی سوالات شما هستیم .
موفق و پیروز باشید.
سلام مهندس شفیعی
وقتی inspect میگیریم تو موبایل لودینگ دور میزنه و چیزی لود نمیشه اما دسکتاپ درست کار میکنه
علت چیه ؟
سلام مهندس شفیعی توصیه شما اینه از اسکرول بینهایت استفاده کنیم ؟
و اینکه در اسکرول بینهایت در ابتدا فقط چند ایتم اولی لود میشه درسته وبقیه بعد از اسکرول لود میشن ؟
سلام. بله
خیلی خیلی ممنونم از سایتتون وااقعا مطالب عاالی بودن خسته نباشید میگم به مدیر محترم سایت
من برای هیچ سایتی نظر نذاشتم اولین باره که دارم برای این سایت نظر میزارم
(مطلاب رو معمولا از همه سایت ها دارن اما کامل بودن و مفهومی بودن مطلب خیلی مهه که متاسفانه کم پیدا میشه).
تشکر میکنم .
سلام. خیلی خوشحالیم که مفید واقع شده.
ممنون از نظر مثبت و پر انرژی شما.
موفق باشید.
با سلام
تشکر بابت آموزش مفیدتون. فقط اگر امکانش هست لطفا سورس کد این آموزش رو قرار بدید خیلی خوب میشه. تو بخش دانلود باکس فیلدی برای ارسال ایمیل و دریافت لینک وجود نداره.
باتشکر
سلام. بفرمایید از اینجا دانلود بفرمایید
https://netparadis.com/wp-content/uploads/2020/02/php-pagination-mysql-database-example-script-with-previous-next-like-google-netparadis.com_.zip
سلام
سپاسگزارم