[PHP] Jak zrobić uniwersalne porcjowanie wyników na stronie, aby nie pokazywała się cała zawartość tablicy lub tekstowej bazy danych?
Chcesz dane z pliku tekstowego lub tablicy podzielić na porcje, aby użytkownik mógł przeglądać kilka mniejszych stron z wynikami zamiast jednej ogromnej. Chcesz decydować ile odpowiedzi znajdzie się na każdej ze stron i jak długi będzie pasek nawigacyjny.
Porcjowanie wyników zapytania to ważna czynność podczas pracy z tekstowymi bazami danych lub tablicami, gdy wyniki przekraczają 30 rekordów. Niektóre bazy danych lub tablice liczą nawet kilk tysięcy pozycji więc pokazanie ich wszystkich na jednej stronie WWW nie jest możliwe.
Zamiast pokazywać po kilkaset wyników, można je łatwo porcjować. Nie jest ważne co porcjujesz - mogą to być wpisy na forum, dedykacje w księgach gości, informacje o książkach lub zawartość katalogu produktów w jakimś sklepie.
Opisany poniżej skrypt nie tylko świetnie porcjuje tablice lub tekstowe bazy danych, ale jest niesamowicie elastyczny. Możesz ustawiać ilość danych przypadających na jedną stronę, przekazywać dodatkowe zmienne podczas przechodzenia pomiędzy stronami czy ustalać jak szeroki (np. od 1 do 10) będzie pasek służący do poruszania się pomiędzy stronami z wynikami.
Dodatkowo oprócz klikania na poszczególne strony możesz wykorzystać pola "następna" i "poprzednia", które automatycznie przenoszą o jedną stronę do przodu lub do tyłu. Zobacz jak napisać uniwersalny skrypt do porcjowania wyników:
<?
function pasek($l_odp,$l_odp_nastronie,$l_odp_napasku,$skrypt,$a) {
$l_odp_podz = intval($l_odp / $l_odp_nastronie);
$l_odp_podz_mod = $l_odp % $l_odp_nastronie;
if ($l_odp_podz_mod>0) $l_odp_podz++;
if ($a<0) $a=0;
if ($a>=$l_odp_podz) $a=$l_odp_podz-1;
$start = $a-1;
if ($a>0) {$pop="<a href=\"".$skrypt."a=$start\"><<<
poprzednia</a> - ";}
else {$pop = "<font color=gray><<< poprzednia </font> - ";}
if ($a<$l_odp_napasku) {$koniec = $l_odp_napasku*2+1;}
else {$koniec = $a+$l_odp_napasku+1;}
if ($a<=$koniec-$l_odp_napasku) {$star=$a-$l_odp_napasku;}
if ($a>=$l_odp_podz-$l_odp_napasku) {$star=$l_odp_podz-$l_odp_napasku*2-1;}
if ($koniec>$l_odp_podz) $koniec = $l_odp_podz;
if ($star<0) $star=0;
for ($i=$star; $i<$koniec; $i++) {
if ($i <> $a) { $pasek .= "<a href=\"".$skrypt."a=$i\">";}
else { $pasek .= "<font color=red><b>"; }
if ($l_odp_podz<>1) {$pomocniczy = $i+1;}
if ($i<>$a) { $pasek .= "$pomocniczy</a> "; }
else {$pasek .= "$pomocniczy</b></font> ";}
}
$dalej = $a+1;
if ($a<$l_odp_podz-1)
{$nas="- <a href=\"".$skrypt."a=$dalej\">następna >>> </a>";}
else { $nas = "- <font color=gray>następna >>> </font>";}
if ($pomocniczy>0) {$br= "<br> $pop $pasek $nas"; }
echo "<center> znalezionych: <b>$l_odp</b> na <b>$l_odp_podz</b>
stronach $br</center>";
}
$l_odp_nastronie=10;
$l_odp_napasku=5;
$skrypt="index.php?";
// wczytanie pliku
$baza=file("baza.txt");
// uzyskanie ilości linijek/rekordów
$l_odp = count($baza);
pasek($l_odp,$l_odp_nastronie,$l_odp_napasku,$skrypt,$a);
// wyświetlenie wyników z bazy danych
$start=$a*$l_odp_nastronie;
if ($start+$l_odp_nastronie>$l_odp)
$l_odp_nastronie=$l_odp % $l_odp_nastronie;
for ($i=$start;$i<$start+$l_odp_nastronie;$i++) {
echo $baza[$i]."<p>";
}
?>
Bazą danych jest plik tekstowy, który zawiera jeden rekord w jednej linijce. Może to być również tablica $baza[], która ma dowolną ilość elementów. Docelowo rekordy z pliku i tak umieszczone są za pomocą funkcji file() w tablicy $baza[].
Działania funkcji pasek() opisywać nie będę, ponieważ algorytm jest dosyć złożony i zależy od wielu warunków. Generalnie wszystko jest czystą matematyką. Funkcja rozbija liczbę wszystkich odpowiedzi na poszczególne składowe, a więc liczbę stron, aktualną pozycję czy ilość cyfr w menu. Obliczenia są uzależnione od wielu czynników i warunków początkowych.
Ważne aby do funkcji pasek() przekazać pięć zmiennych:
$l_odp - liczba wszystkich rekordów w bazie/tablicy (możliwych odpowiedzi)
$l_odp_nastronie - liczba rekordów na jednej stronie
$l_odp_napasku - liczba cyfr na pasku - wystarczy podać tylko połowę planowanej liczby zwiększonej o jeden, np. 5 to w rzeczywistości 11 cyfr (1,2,3,4,5),6,(7,8,9,10,11). Określa ona ilość cyfr po prawej i lewej stronie względem środka.
$skrypt - nazwa skryptu bez parametrów np. index.php? lub z dodatkowymi parametrami index.php?x=123&c=sort&
$a - zmienna określająca numer strony z wynikami - to właśnie ona określa, która porcja wyników będzie pokazana
Warto poeksperymentować z różnymi opcjami aby dostować skrypt do własnych potrzeb. Opcje są bardzo elastyczne i z powodzeniem można skrypt zastosować do dowolnych projektów.
Funkcja pasek() tak na prawdę nie porcjuje wyników... Tworzy ona jedynie pasek do nawigacji pomiędzy stronami z wynikami i ustala zmienną $a. Właściwe porcjowanie zachodzi na etapie pokazywania zawartości pliku lub tablicy. Cały plik wczytywany jest do tablicy i następnie jej fragment pokazywany jest na ekranie za pomocą pętli for() z podanymi zakresami rekordów.
Liczbę odpowiedzi przypadających na stronę podajemy pod funkcją pasek(), ustalamy tam również liczbę cyfr na pasku i skrypt (oraz ewentualne parametry jakie ma przekazywać). Brakuje jeszcze ilości wszystkich rekordów. Można ją pobrać za pomocą funkcji count(). Jeżeli liczba rekordów w tablicy nie zmienia się, możesz tą wartość przypisać na stałe.
Następnie wyświetlany jest pasek nawigacyjny i wybrana porcja wyników. Kolejność może być dowolna - najpierw porcja wyników, a na dole pasek nawigacyjny.
Jak widzisz, bez problemu można w ten sposób przeglądać pliki i tablice o tysiącach linijek/rekordów. Wszystko odbywa się szybko i bardzo wygodnie dla użytkownika.