Navigering af en søgeside ved hjælp af php. Sidenavigation i PHP

/* 09.07.2008 */

Paged output (PHP og MySQL)

Ganske ofte er der på et websted behov for at vise en stor mængde information af samme type, og for at lette opfattelsen bør den opdeles i dele, dvs. implementere side for side visning af disse oplysninger. denne beslutning Brugt søgemaskiner når du viser søgeresultater, fora, opslagstavler osv. denne artikel beskriver, hvordan man implementerer sideoutput ved hjælp af MySQL og PHP.

Til at begynde med bemærker jeg, at artiklen ikke lærer, hvordan man arbejder med en database og PHP, men giver en forklaring på implementeringen og giver en klar til brug (sidenavigation).

Lad os begynde! Lad os sige, at der er en database (MySQL), for eksempel med annoncer. Vi skal implementere deres visning på webstedet i portioner af 20 stykker pr. side. For at flytte mellem dele skal du nederst på hver side oprette links med antallet af "portioner" (sideetiketter):

Gå...

Henter data i bidder

For at vælge ALLE annoncer fra databasen skal du bruge en forespørgsel som:

VÆLG * FRA tabel1

Selvfølgelig er dette en forenklet version, og i rigtige opgaver indeholder anmodningen oftest forskellige forhold(HVOR, BESTIL EFTER ... udsagn).

For at denne forespørgsel kan foretage valg i portioner, skal du tilføje operatoren til den BEGRÆNSE:

LIMIT sætningssyntaks: LIMIT række_antal

Valgfri parameter offset fortæller dig, hvor mange rækker fra begyndelsen af ​​prøven du skal springe over, og række_antal angiver hvor mange rækker der skal vælges, dvs. LIMIT 0, 20 (eller bare LIMIT 20 udeladelse af nul offset) vælger de første 20 rækker (række 0 til 19), og LIMIT 40, 20 angiver at springe 40 over (række 0 til 39) og vælge de næste 20 (dvs. række 40 til 59 vil blive valgt).

Bemærk venligst, at rækkerne i prøven er nummereret fra nul, ikke fra én.

Så forespørgslerne til vores annonceeksempel ville være:

#query for at vælge side 1: VÆLG * FRA tabel1 LIMIT 0, 20 #query for at vælge side 2: VÆLG * FRA tabel1 LIMIT 20, 20 #query for at vælge side 3: VÆLG * FRA tabel1 LIMIT 40, 20

etc. offset stige med 20 for hver efterfølgende side, og række_antal er altid lig med 20.

Det skal også bemærkes, at LIMIT-operatoren i en forespørgsel kommer i rækkefølge efter WHERE , GROUP BY , HAVING , ORDER BY , men hvis du er ny i MySQL, kan du sige, at den kommer i slutningen af ​​forespørgselslinjen (efterfulgt af operatører, der ret sjældent bruges).

Den anden del, vi skal beskæftige os med, er linjen med sideetiketter...

Sidegenveje

For et eksempel på de tredje tyve annoncer kunne etiketten f.eks. se sådan ud:

side nummer 3

Når du klikker på dette link, startes obyavleniya.php scriptet, som har adgang til parameteren page_number, hvilket indikerer, at der anmodes om 3 20 annoncer - side 3. Scriptet springer de første 40 annoncer over og vælger de næste 20.

For at vise denne genvejsrække skal du vide samlet antal sider (for at vide, hvor mange etiketter der skal "tegnes"). Vi kan få det ved at dividere det samlede antal annoncer med antallet af annoncer på siden og afrunde resultatet til et højere heltal. Det vil sige, at hvis der i vores eksempel, lad os sige, kun er 107 annoncer, og vi viser 20 af dem på hver side, så vil antallet af sider være: 107 / 20 = 5,35, dvs. 5 hele sider(20 annoncer hver) + en ufuldstændig (7 annoncer), i alt, rundet op, får vi 6 sider (der vil følgelig være 6 etiketter).

For at tælle det samlede antal annoncer er der to måder. Den første måde er at køre en separat opsummerende forespørgsel, der næsten ligner forespørgslen til udvælgelse af data, kun uden den begrænsende LIMIT-operator og unødvendige sorteringsoperationer (ORDER BY), for eksempel:

#query for valg af annoncer 3 sider VÆLG * FRA tabel1 WHERE category_id="89" OG ... BESTIL EFTER publiceringsdato DESC LIMIT 40, 20 #query for at tælle ALLE annoncer i databasen VÆLG ANTAL(*) FRA tabel1 WHERE category_id="89" OG ...

Den første forespørgsel vælger annoncer, og den anden beregner deres samlede antal ved hjælp af COUNT-funktionen. I praksis kan datahentningsforespørgsler være ret besværlige og tunge, så en ekstra tung forespørgsel til optælling er ikke den mest "nødvendige" operation. Desuden er denne vej ikke så elegant som den anden...

MySQL 4.0.0 introducerede fantastiske ting som funktionen FOUND_ROWS og relateret til det SQL_CALC_FOUND_ROWS- mulighed for SELECT-sætningen.

Lad os overveje den anden mulighed for at beregne det samlede antal rækker:

VÆLG SQL_CALC_FOUND_ROWS* FRA tabel1 WHERE category_id="89" OG ... BESTIL EFTER publiceringsdato DESC LIMIT 40, 20 SELECT FOUND_ROWS()

Igen foretager den første anmodning et udvalg af annoncer, og den anden får det samlede antal, men...

Anmod om et udvalg af annoncer i I dette tilfælde adskiller sig fra valget fra den første mulighed kun i nærværelse af indstillingen SQL_CALC_FOUND_ROWS. Denne mulighed instruerer MySQL, sammen med datavalget, at lave og tælle alle de rækker, som forespørgslen ville returnere uden LIMIT-operatoren. De der. faktisk denne anmodning inkluderer i en skjult form anmodningen COUNT fra den første mulighed. I dette tilfælde returneres selve det beregnede beløb ikke, men huskes af serveren. Nu, for at finde ud af dette tal, skal du udføre en anmodning med funktionen FOUND_ROWS (i dette tilfælde udfører serveren ingen beregninger, den returnerer blot det, den huskede tidligere).

Den anden mulighed ser bestemt mere elegant ud og kan også give nogle hastighedsgevinster.

Samler det hele

Nu ved du alt, hvad du har brug for, og jeg kan give en algoritme, der beskriver logikken i obyavleniya.php-scriptet til paginering, som lanceres, når brugeren kommer ind på annoncesiden...

  1. Først og fremmest, når vi kører scriptet, ser vi på hvilken side brugeren anmoder om (i vores eksempel er dette angivet med parameteren page_number);
  2. Baseret på nummeret på den anmodede side, beregner vi offset-parameteren for LIMIT-operatøren;
  3. vi kører en forespørgsel for at vælge annoncer med operatoren LIMIT offset, 20 (hvor 20 er antallet af annoncer, der vises på siden i vores eksempel);
  4. vi får det samlede antal annoncer i databasen;
  5. Ud fra punkt 4 beregner vi det samlede antal annoncesider og opretter en streng af etiketter.

Det er alt. Nu håber jeg, at du kan skrive dit eget manuskript, eller bruge mit, og forstå essensen af, hvordan det fungerer.

PHP Paging klasse til personsøgning

Nu vil jeg give et eksempel på, hvordan sidenavigation er organiseret ved hjælp af PHP-klassen Paging.

//tilslut Paging-klassen require("paging.inc.php "); //tilslut til databasen$_DB = new mysqli($host,$user,$passwd,$db_name); //opret en forekomst af Paging-klassen //som en parameter sender vi den en pointer til MySQL-forbindelsen$_PAGING = ny personsøgning($_DB); //udfør en almindelig dataanmodning uden at bekymre dig //om paginering via get_page-metoden for Paging-klasseobjektet$r = $_PAGING->get_page("VÆLG * FRA tabel1"); while($row = $r->fetch_assoc()) ( //behandle de data, der modtages fra databasen, SOM SOM VANLIGT og vis dem til brugeren } //viser en informationslinje som: "vist fra 1 til 20 af 107" echo $_PAGING->get_result_text()." annoncer"; //vis genvejslinks til de forrige og næste sider echo "Sider: ".$_PAGING->get_prev_page_link()." ".$_PAGING->get_next_page_link()."

"; //samt en linje med sidetal (hovedgenveje) echo $_PAGING->get_page_links(); ?>

Det eneste, der gør dette script anderledes end almindeligt manuskript uden personsøgning, skyldes det, at anmodningen om en prøve af data, der skal opdeles i dele, ikke sker gennem mysqli->query() , men gennem metoden get_page() implementeret i Paging-klassen, samt tre sidste linjer som viser etiketter og en valgrapportlinje.

P.S

P.S.: Jeg præsenterer dette efterskrift mere for fuldstændighedens skyld end som faktisk relevant information for de fleste læsere.

Brugen af ​​SQL_CALC_FOUND_ROWS og FOUND_ROWS() har nogle faldgruber, når de bruges i UNION-forespørgsler, da LIMIT-sætninger kan bruges flere steder, og kan påvirke både individuelle SELECT-sætninger i UNION og de generelle UNION resultat generelt. Formålet med SQL_CALC_FOUND_ROWS for UNION er at tælle antallet af rækker, der vil blive returneret uden en global LIMIT. Derfor skal betingelserne for brug af SQL_CALC_FOUND_ROWS med UNION-forespørgsler angives:

  • Nøgleordet SQL_CALC_FOUND_ROWS skal vises i det første SELECT erklæring ;
  • Værdien af ​​FOUND_ROWS() vil kun være nøjagtig, hvis UNION ALL bruges. Hvis UNION er angivet uden ALL, forekommer duplikat-eliminering, og værdien af ​​FOUND_ROWS() vil kun være omtrentlig;
  • Hvis LIMIT ikke er til stede i UNION, ignoreres SQL_CALC_FOUND_ROWS, og antallet af rækker i den midlertidige tabel, der er oprettet for at udføre UNION, returneres.

Det manuskript vil tillade dig at vise ikke kun pile på " forrige side"og" Næste side", som i artiklen, men også, hvis det ønskes, vil hjælpe med at vise en ensartet liste over links til alle sider på webstedet. Du kan se hvordan det ser ud på min hjemmeside – gå bare ned til hjemmeside websted.

Brug phpmyadmin (eller sql), opret en tabel (navnet er op til dig, jeg kaldte opt) med to felter. Kald det første felt-id, det andet str. Begge felter skal have numerisk type(int), tildel auto_increment til id-feltet. Dette bord vil gemme numerisk værdi(i str-feltet), som bestemmer antallet af indlæg, der vises på én side.

Alt andet er enkelt. Vi laver en anmodning og henter denne numeriske værdi, sætter den i en variabel, for eksempel $num . Vi bestemmer det samlede antal indlæg (beskeder) i databasen og indtaster denne værdi i $posts-variablen. Find det samlede antal sider på webstedet ($total) og rund ned. Vi beregner ud fra hvilket indlæg det er nødvendigt at vise beskeder (indlæg) på denne side ($start). Vi laver en anmodning til tabellen med indlæg og begrænser den med en grænse ($num), vi specificerer også parameteren ($start), hvorfra output af poster vil begynde. Nu er der kun tilbage at arrangere links til de relevante sider i overensstemmelse hermed, og voila, du er klar. Mere Detaljeret beskrivelse manuskript kan ses direkte i koden.

$result77 = mysql_query("SELECT str FROM opt", $db); $myrow77 = mysql_fetch_array($result77); // antal indlæg på én side $num = $myrow77["str"]; // Uddrag fra URL nuværende side@$page = $_GET["side"]; // Bestem det samlede antal meddelelser i databasen $result00 = mysql_query("SELECT COUNT(*) FROM posti"); $temp = mysql_fetch_array($result00); $posts = $temp; // Find det samlede antal sider $total = (($posts - 1) / $num) + 1; $total = interval($total); // runde den aktuelle side $page = intval($page); // Hvis $page-variablen er mindre end 0 eller tom // tildel $page 1 // Og hvis værdien af ​​$page er over $total, // tildel $page værdien af ​​$total-variablen if(empty($ side) eller $side< 0) $page = 1; if($page >$total) $side = $total; // Beregn ud fra hvilket tal // beskeder skal vises $start = $side * $num - $num; // Vælg $num posts startende fra tallet $start // -----MINI POSTS----- $result = mysql_query("VÆLG * FRA posti BESTIL EFTER dato DESC LIMIT $start, $num ",$db );

//Vis alle indlæg i en løkke

// Tjek om tilbagepile er nødvendige hvis ($page != 1) $pervpage = "Første forrige"; // Tjek om fremadpile er nødvendige, hvis ($page != $total) $nextpage = "Næste Sidste"; // Find de to nærmeste sider fra begge kanter, hvis de findes if($page - 2 > 0) $page2left = " ". ($side - 2) " "; if($page - 1 > 0) $page1left = "". ($side - 1) " "; if($side + 2<=$total) $page2right = " ". ($page + 2) .""; if($page + 1 <=$total) $page1right = " ". ($page + 1) .""; // выводим ссылки echo $pervpage.$page2left.$page1left."".$side."".$page1right.$page2right.$nextpage;

Fordelen ved denne navigation er, at alle sider på siden kan findes inden for 3 klik fra hovedsiden. Denne funktion kan f.eks. være nyttig, når du arbejder med SAPE-tjenesten.

Problemet med at implementere sidenavigation står ofte over for nybegyndere PHP-programmører. Opdeling af omfangsrig tekst i separate sider bruges i mange webapplikationer, lige fra gæstebøger og fora til forskellige mapper. Lad os
Lad os løse dette problem.
Så hvad skal vi bruge for at implementere sidenavigation? Lad os for eksempel tage en gæstebog, der indeholder flere hundrede beskeder, hvor du vil vise X beskeder på siden.
Lad os se mere specifikt på problemet. Brugermeddelelser gemmes i en database stolpe med følgende struktur:

  • id – besked nummer,
  • tekst – beskedtekst,
  • navn - forfatterens navn,
  • tid – skabelsestid.

Som et resultat er vi nødt til at få X-meddelelser output til siden og også organisere praktisk navigation, for eksempel sådan:

<< < ..2|3|4|5|6.. > >>

hvor 4 er den aktuelle side. For at spore den aktuelle side bruger vi parameteren side, sendt via URL. F.eks:

www.myserver.com/index.php?page=X.

Her er X sidetallet (lad f.eks. X være lig med 25).

Nu, efter denne korte introduktion, kan vi begynde selve implementeringen.

// Opret forbindelse til databasen
inkludere "config.php" ;
// Variablen gemmer antallet af meddelelser, der vises på siden
$num = 25 ;
// Hent den aktuelle side fra URL'en
$side = $_GET ["side" ];
// Bestem det samlede antal meddelelser i databasen
$result = mysql_query ("VÆLG ANTAL(*) FRA indlæg" );
$posts = mysql_result($result, 0);
// Find det samlede antal sider
$total = interval (($posts - 1 ) / $num ) + 1 ;
// Bestem begyndelsen af ​​beskeder for den aktuelle side
$side = interval($side);
// Hvis $side er mindre end én eller negativ
// gå til den første side
// Og hvis den er for stor, så gå til den sidste
if(empty($page ) eller $page< 0 ) $page = 1 ;
if($side > $total ) $side = $total ;
// Beregn ud fra hvilket tal
// meddelelser skal vises
$start = $side * $num - $num ;
// Vælg $num beskeder startende fra nummer $start
$result = mysql_query ("VÆLG * FRA post LIMIT $start, $num" );
// I en loop overfører vi forespørgselsresultaterne til $postrow-arrayet
while ($postrow = mysql_fetch_array ($result))
?>

Dette afslutter første del. Todimensionelt array postrow gemmer alle felter i posttabellen, der er nødvendige for at vise siden. Her er et eksempel på, hvordan du kan organisere meddelelsesoutput.

ekko "

" ;
for($i = 0 ; $i< $num ; $i ++)
{
ekko "


" ;
}
ekko "
" . $postrow [ $i ][ "navn" ]. " " . $postrow [ $i ][ "tid" ]. "
" . $postrow [ $i ][ "tekst" ]. "
" ;
?>

Nu skal vi organisere navigationen. Vi formulerer komponenterne til fremtidig navigation.
Vi vil placere pilekoderne "til begyndelsen" og "tilbage" i én variabel, og vi vil også gøre det samme med pilene "til slutningen" og "frem".

// Tjek om tilbagepile er nødvendige
if ($side != 1 ) $pervpage = "<<
. ($side - 1) . ">< " ;
// Tjek om fremadpile er nødvendige
if ($page != $total ) $nextpage = " ">>
. $total. ">>>" ;

// Find de to nærmeste sider fra begge kanter, hvis de findes
if($page - 2 > 0 ) $page2left = " " . ($page - 2 ) ." | " ;
if($page - 1 > 0 ) $page1left = " " . ($page - 1 ) ." | " ;
if($side + 2<= $total ) $page2right = " | " . ($page + 2) ."" ;
if($side + 1<= $total ) $page1right = " | " . ($page + 1) ."" ;

// Vis menu
echo $pervpage . $page2left . $page1venstre . " ". $side."" . $page1right . $page2right . $nextpage ;

Godaften brugere. I har sikkert ofte mødtes sidenavigation på websteder. I denne lektion lærer vi, hvordan man laver en sådan side-for-side-navigation.

Som sædvanlig sender jeg en demoversion og kildemateriale til denne lektion. I demoversionen kan du se sidenavigationen, som vi nu vil lave.

Til denne tutorial skal vi bruge en database, en kørende lokal server, et navigationsscript og din tålmodighed.

Trin 1. Database

Først og fremmest skal vi oprette en database og en bruger. Og opret også en tabel og fyld den med information. I mit eksempel hedder databasen navigation, og bordet hedder nyheder.

Se skærmbilledet nedenfor for tabelstrukturen:

Tabellen består af 3 felter − id, titel, tekst.

Trin 2. Opret forbindelse til databasen

Nu skal vi skrive en forbindelse til databasen. For at gøre dette oprettede jeg en ny fil og kaldte den cfg.php. I denne fil skrev jeg følgende kode:

Der er ikke noget kompliceret i denne kode. Vi skrev en almindelig forbindelse til databasen og specificerede en betingelse, hvis noget pludselig går galt, får vi en fejl. Vi specificerede også databasekodningen - utf8.

Trin 3. Output information fra databasen

Lad os nu oprette en fil og kalde den index.php. Dette vil være vores hovedfil. Det vil vise poster, og her vil vi oprette sidenavigation. Glem ikke at arkivere index.php forbinde fil cfg.php. For at gøre dette skal du skrive følgende kode et sted i begyndelsen af ​​siden:

For at få vist information fra databasen skrev jeg i filen index.php her er koden:

"; ) while($array = mysql_fetch_array($query)); ?>

Der er heller ikke noget usædvanligt i denne kode. Vi har udvalgt alle oplysninger fra tabellen nyheder og output det ved hjælp af en loop gøre imens.

Trin 4. Første del af scriptet

Nu hvor vi har alle oplysningerne vist, kan vi bruge den første del af scriptet. For at gøre dette i filen index.php Indsæt koden, før du prøver oplysningerne:

$num = 5; $side = $_GET["side"]; $result00 = mysql_query("VÆLG ANTAL(*) FRA nyheder"); $temp = mysql_fetch_array($result00); $posts = $temp; $total = (($posts - 1) / $num) + 1; $total = interval($total); $side = interval($side); if(empty($page) eller $page $total) $page = $total; $start = $side * $num - $num;

Denne linje $num = 5; er ansvarlig for antallet af artikler på siden. I stedet for tallet 5 kan du sætte din egen værdi.
Du skal også ændre selve valginformationen lidt og tilføje følgende til den:

$query = mysql_query("VÆLG * FRA nyheder BESTIL EFTER id LIMIT $start, $num");

Vores kode skulle nu se sådan ud:

"; echo $array["tekst"]; echo "

"; ) while($array = mysql_fetch_array($query)); ?>

Trin 5. Vis navigationen

I dette trin skal vi vise selve navigationen, som vil se ud 1 | 2 | Næste | Sidst. For at gøre dette i filen index.php under den forrige kode åbne php-tags og skriv følgende kode i dem:

0) $page5left = " ". ($side - 5) ." | "; if($page - 4 > 0) $page4left = " ". ($side - 4) ." | "; if($page - 3 > 0) $page3left = " ". ($side - 3) ." | "; if($page - 2 > 0) $page2left = " ". ($side - 2) ." | "; if($page - 1 > 0) $page1left = " ". ($page - 1) ." | "; if($page + 5 ". ($page + 5) .""; if($page + 4 ". ($page + 4) .""; if($page + 3 ". ($page + 3) .""; if($page + 2 ". ($page + 2) .""; if($page + 1 ". ($page + 1) .""; // Vis menuen, hvis der er mere end én side hvis ($total > 1) (Error_Reporting(E_ALL & ~E_NOTICE); echo "

"; ekko $pervpage.$page5left.$page4left.$page3left.$page2left.$page1left." ".$side."".$page1right.$page2right.$page3right.$page4right.$page5right.$nextpage; ekko "

Trin 6. Resultat af det udførte arbejde

Det er alt, denne lektion er slut. Tak for din opmærksomhed!

Du kan se den fulde kode for alle sider og scriptkoden i kilderne. Du kan downloade kildekoden fra linket i begyndelsen af ​​lektionen helt gratis og uden reklame.

Lektionen blev forberedt til dig af webstedsteamet.