ООП Странициране с избор на полета от заявката
19-01-2011
Вчера се оказах в нужда за точно подобно странициране за система за съобщения. Може да бъде полезно за много неща, обаче. Писах го възможно най-просто и мисля, че се разбира доста лесно кое за какво служи. Освен това сложих и коментари, така че да бъде и отчасти обучително.
Да започваме:
Нужни са ни 3 файла:
class.php - това е самия клас. Той е най-важното.
config.php - файла за връзка с базата данни
index.php - файла, в който ще показваме всичко

Първо връзката с база данни:
config.php

<?php
$host = 'localhost';
$user = 'root';
$pass = '';
$daba = 'test';

$link = mysql_connect($host, $user, $pass) or die(mysql_error());

$db = mysql_select_db($daba, $link) or die(mysql_error());
?>

Всичко по този файл би трябвало да е ясно. Указваме сървъра, името и паролата за базата данни и нейно име. По-надолу се свързваме със сървъра и избираме базата. Променливите не са важни в случая.

Следва самия клас:
class.php

<?php
class pagination{
private $query, $perpage, $total, $rows;

function __construct($p, $q, $r){
$this->perpage = (int)$p;
$this->query = $q; //присвояване на
$this->rows = $r; //променливите за целия клас
$this->total = $this->totalpages(); //изчисляване на броя страници
}

function totalpages(){ //изчислява коя е последната страница
$result = mysql_query($this->query) or die(mysql_error());
$pages = mysql_num_rows($result);// считам, че тук няма нищо, което
$pages = ceil($pages/$this->perpage);// да се нуждае от обяснение
return $pages;
}

function pages($current){ //показва страниците
$current = (int)$current; //взимаме текущата страница за да можем да я отбележим
for($i=1; $i<=$this->total; $i++){ //показваме страниците от 1 до последната
if($i==1)
$txt = "Първа"; //променяме текста на първата
elseif($i==$this->total)
$txt = "Последна"; //променяме и текста на последната
else
$txt=$i; //текст на страниците от 2 до (последна-1)
if($i!=$current)
echo '<a style="margin-left: 2px; border: 1px solid black; padding: 3px; text-decoration: none; color: black;" href="?page='.$i.'">'.$txt.'</a>';
else
echo '<font style="margin-left: 2px; border: 1px solid black; padding: 3px; text-decoration: none; color: red;">'.$txt.'</font>';
}
}

function display($page){ //показваме информацията
$page = (int)$page; //страница за показване
$page = (($page>=1) && ($page<=$this->total)) ? $page : 1;
//подсигуряваме валидността на номера на страницата
$start = $this->perpage*($page-1); //начален ред за показване от базата данни
$query = $this->query." LIMIT ".$start.", ".$this->perpage; //лимитираме заявката
$result = mysql_query($query);
while($row = mysql_fetch_assoc($result)){ //показваме редовете от заявката
echo "<tr>";
foreach($this->rows as $var) //избираме полета за показване
echo "<td>".$row[$var]."</td>";
echo "</tr>";
}
}
}
?>

През няма и 2 реда има коментари. Ако има нещо неясно можете да ме питате допълнително. Няма да се спирам по-подробно на всичко. Най-интересната част е тази:

while($row = mysql_fetch_assoc($result)){ //показваме редовете от заявката
echo "<tr>";
foreach($this->rows as $var) //избираме полета за показване
echo "<td>".$row[$var]."</td>";
echo "</tr>";
}

От тук $this->rows държи масива с полетата, който сме задали във файла, в който показваме всичко. Него ще видите по-долу. foreach се изпълнява за всеки елемент от масива, като елемента се зарежда в променливата $var. После от while цикъла, който пък зарежда $row с масив от всички полета, които сме извикали със заявката, се извиква именно полето $var. Малко неясно е обяснението, но когато го пробвате, ще разберете за какво точно става въпрос.

И дойде ред на файла, в който извеждаме резултатите:
index1.php

<meta http-equiv="content-type" content="text/html; charset=windows-1251">
<?php
include("config.php");
include("class.php");

$per_page = "5"; //брой редове от заявката на страница

$query = "SELECT * FROM messages"; //заявка към базата данни

$rows = array("id", "date", "reciever_id"); //полета, които ще използваме при показването

$pagination = new pagination($per_page, $query, $rows);
//зареждаме $pagination с класа и му даваме началните параметри за __construct()
?>
<table border="1">
<tr>
<?php foreach($rows as $var) echo "<td>".$var."</td>"; ?>
//създаваме първия ред от таблицата, като използваме имената на полетата.
//може да се използва втори масив за да не се виждат реалните имена на полетата.
</tr>
<?php $pagination->display($_GET['page']); ?>
</table><br>
<?php echo $pagination->pages($_GET['page']); ?>

Тук виждате масива, който указва полетата, които да използваме при заявката. Ако съответните полета не съществуват когато заявката се изпълни, то на тяхно място излизат празни стойности.
Ще кръстим тази страница index1.php.
Тук заявката е много орязана и почти никога не се използват такива заявки. За тази цел можем да използваме и по-сложни заявки. Нека разгледаме един такъв случай - ще кръстим тази страница index2.php
index2.php

<meta http-equiv="content-type" content="text/html; charset=windows-1251">
<?php
include("config.php");
include("class.php");

$per_page = "5"; //брой редове от заявката на страница

$query = "
SELECT `messages`.*, `users`.`username`
FROM messages
JOIN users ON `messages`.`reciever_id`=`users`.`id`
ORDER BY `messages`.`id` DESC"; //заявка към базата данни

$rows = array("id", "date", "username"); //полета, които ще използваме при показването

$pagination = new pagination($per_page, $query, $rows);
?>
<table border="1">
<tr>
<?php foreach($rows as $var) echo "<td>".$var."</td>"; ?>
</tr>
<?php $pagination->display($_GET['page']); ?>
</table><br>
<?php echo $pagination->pages($_GET['page']); ?>

Както виждате можем да използваме и JOIN за да включим други таблици от базата данни.
И в двата index файла използвам charset=windows-1251, защото в класа първата и последната страници се именуват на български. При добро желание може да се използват други променливи в __construct за да може да се използват различни езици.

Надявам се да съм Ви бил полезен!
Демо на двата index файла:

Съжалявам, че не мога да дам реално ДЕМО.
Архив с всички файлове:
Архив

Урокът е авторски и преписването му в други сайтове е строго нежелателно. Ако все пак ще го преписвате, споменете името на автора :)

ventsi_konov aka LucasBoy



/ Трябва да сте регистриран за да напишете коментар /
От: tedobedo
16:19 25-01-2011
Браво! Урока е доста добър!
btw: Случайно да учиш в ОМГ? :D
От: ventsi_konov
22:38 25-01-2011
Не беше много случайно - имаше изпити, записвания :D Уча, да :)
От: dj_vansa
11:05 18-05-2011
Урока ти е доста добър, но имам една малка забележчица, много лошо си сложил всички линкове към една променлива практически метода "pages", за повече информация не става:)
1