Navigere på en søkeside ved hjelp av php. Sidenavigering i PHP

/* 09.07.2008 */

Sidet utgang (PHP og MySQL)

Ganske ofte på et nettsted er det behov for å vise en stor mengde informasjon av samme type, og for å lette oppfatningen bør den deles inn i deler, dvs. implementere side-for-side-visning av denne informasjonen. Denne avgjørelsen brukt søkemotorer når du viser søkeresultater, fora, oppslagstavler osv. denne artikkelen beskriver hvordan du implementerer sideutdata ved å bruke MySQL og PHP.

Til å begynne med legger jeg merke til at artikkelen ikke lærer hvordan man jobber med en database og PHP, men gir en forklaring på implementeringen og gir en klar til bruk (sidenavigasjon).

La oss begynne! La oss si at det er en database (MySQL), for eksempel med annonser. Vi må implementere visningen deres på nettstedet, i porsjoner på 20 stykker per side. For å flytte mellom deler, nederst på hver side må du opprette lenker med antall "porsjoner" (sideetiketter):

Gå...

Henter data i biter

For å velge ALLE annonser fra databasen trenger du et søk som:

VELG * FRA tabell1

Selvfølgelig er dette en forenklet versjon, og i virkelige oppgaver inneholder oftest forespørselen ulike forhold(HVOR, BESTILL ETTER ... utsagn).

For at denne spørringen skal gjøre valg i porsjoner, må du legge til operatøren i den GRENSE:

LIMIT-setningssyntaks: LIMIT row_count

Valgfri parameter offset forteller deg hvor mange rader fra begynnelsen av prøven du må hoppe over, og rad_antall angir hvor mange rader som må velges, dvs. LIMIT 0, 20 (eller bare LIMIT 20 utelater null offset) velger de første 20 radene (radene 0 til 19), og LIMIT 40, 20 spesifiserer å hoppe over 40 (radene 0 til 39) og velge de neste 20 (dvs. radene 40 til 59 vil bli valgt).

Vær oppmerksom på at radene i prøven er nummerert fra null, ikke fra én.

Så spørringene for annonseeksemplet vårt vil være:

#query for å velge side 1: VELG * FRA tabell 1 GRENSE 0, 20 #query for å velge side 2: VELG * FRA tabell 1 GRENSE 20, 20 #query for å velge side 3: VELG * FRA tabell 1 GRENSE 40, 20

etc. offsetøke med 20 for hver påfølgende side, og rad_antall alltid lik 20.

Det skal også bemerkes at LIMIT-operatøren i en spørring kommer i rekkefølge etter WHERE , GROUP BY , HAVING , ORDER BY , men hvis du er ny på MySQL, kan du si at den kommer på slutten av spørringslinjen (etterfulgt av operatører som brukes ganske sjelden).

Den andre delen vi må forholde oss til er linjen med sideetiketter...

Sidesnarveier

For eksempel, for et utvalg av de tredje tjue annonsene, kan etiketten se slik ut:

side nummer 3

Når du klikker på denne lenken, lanseres obyavleniya.php-skriptet, som har tilgang til parameteren page_number, som indikerer at 3 20 annonser blir forespurt - side 3. Skriptet hopper over de første 40 annonsene og velger de neste 20.

For å vise denne strengen med snarveier må du vite det totalt antall sider (for å vite hvor mange etiketter som skal "tegnes"). Vi kan få det ved å dele det totale antallet annonser på antall annonser på siden, avrunde resultatet til et høyere heltall. Det vil si at hvis i vårt eksempel, la oss si, det bare er 107 annonser, og vi viser 20 av dem på hver side, vil antall sider være: 107 / 20 = 5,35, dvs. 5 hele sider(20 annonser hver) + en ufullstendig (7 annonser), totalt, rundet opp, får vi 6 sider (det vil følgelig være 6 etiketter).

For å telle det totale antallet annonser, er det to måter. Den første måten er å kjøre en separat oppsummeringsspørring nesten lik spørringen for å velge data, bare uten den begrensende LIMIT-operatoren og unødvendige sorteringsoperasjoner (ORDER BY), for eksempel:

#query for valg av annonser 3 sider VELG * FRA tabell 1 WHERE category_id="89" OG ... BESTILL ETTER publiseringsdato DESC LIMIT 40, 20 #query for å telle ALLE annonser i databasen VELG ANTALL(*) FRA tabell1 WHERE category_id="89" OG ...

Den første spørringen velger annonser, og den andre beregner det totale antallet ved hjelp av COUNT-funksjonen. I praksis kan datainnhenting være ganske tungvint og tungt, så en ekstra tung spørring for telling er ikke den mest "nødvendige" operasjonen. Dessuten er ikke denne veien like elegant som den andre...

MySQL 4.0.0 introduserte flotte ting som funksjonen FOUND_ROWS og relatert til det SQL_CALC_FOUND_ROWS- alternativet for SELECT-setningen.

La oss vurdere det andre alternativet for å beregne det totale antallet rader:

PLUKKE UT SQL_CALC_FOUND_ROWS* FRA tabell 1 WHERE category_id="89" OG ... BESTILL ETTER publiseringsdato DESC LIMIT 40, 20 SELECT FOUND_ROWS()

Igjen, den første forespørselen gjør et utvalg av annonser, og den andre får det totale antallet, men...

Be om et utvalg annonser i i dette tilfellet skiller seg fra valget fra det første alternativet bare i nærvær av alternativet SQL_CALC_FOUND_ROWS. Dette alternativet instruerer MySQL, sammen med datautvalget, å lage og telle alle de radene som spørringen ville returnere uten LIMIT-operatøren. De. faktisk denne forespørselen inkluderer i en skjult form COUNT-forespørselen fra det første alternativet. I dette tilfellet returneres ikke selve det beregnede beløpet, men huskes av serveren. Nå, for å finne ut dette tallet, må du utføre en forespørsel med funksjonen FOUND_ROWS (i dette tilfellet utfører ikke serveren noen beregninger, den returnerer bare det den husket tidligere).

Det andre alternativet ser definitivt mer elegant ut og kan også gi noen hastighetsøkninger.

Sette alt sammen

Nå vet du alt du trenger, og jeg kan gi en algoritme som beskriver logikken til obyavleniya.php-skriptet for paginering, som lanseres når brukeren går inn på annonsesiden...

  1. Først av alt, når vi kjører skriptet, ser vi på hvilken side brukeren ber om (i vårt eksempel er dette indikert av parameteren page_number);
  2. Basert på nummeret på den forespurte siden, beregner vi offset-parameteren til LIMIT-operatøren;
  3. vi kjører et søk for å velge annonser med operatøren LIMIT offset, 20 (hvor, 20 er antallet annonser som vises på siden i vårt eksempel);
  4. vi får det totale antallet annonser i databasen;
  5. Basert på punkt 4 beregner vi det totale antallet annonsesider og lager en etikettstreng.

Det er alt. Nå håper jeg du kan skrive ditt eget manus, eller bruke mitt, og forstå essensen av hvordan det fungerer.

PHP personsøkingsklasse for personsøking

Nå vil jeg gi et eksempel på hvordan sidenavigasjon er organisert ved hjelp av PHP-klassen Paging.

//koble til Paging-klassen require("paging.inc.php "); //koble til databasen$_DB = new mysqli($vert,$bruker,$passwd,$db_navn); //opprett en forekomst av Paging-klassen //som en parameter sender vi den en peker til MySQL-tilkoblingen$_PAGING = ny personsøking($_DB); //utfør en vanlig dataforespørsel uten å bekymre deg //om paginering via get_page-metoden til Paging-klasseobjektet$r = $_PAGING->get_page("VELG * FRA tabell1"); while($row = $r->fetch_assoc()) ( //behandle dataene mottatt fra databasen SOM VANLIG, og vis dem til brukeren } //vis en informasjonslinje som: "Vis fra 1 til 20 av 107" echo $_PAGING->get_result_text()." annonser"; //vis snarveislenker til forrige og neste side echo "Sider: ".$_PAGING->get_prev_page_link()." ".$_PAGING->get_next_page_link()."

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

Det eneste som gjør dette manuset annerledes enn vanlig manus uten personsøking, er dette fordi forespørselen om et utvalg av data som må deles inn i deler ikke gjøres gjennom mysqli->query() , men gjennom get_page()-metoden implementert i Paging-klassen, samt tre siste linjer som viser etiketter og en utvalgsrapportlinje.

P.S

P.S.: Jeg presenterer dette etterskriftet mer for fullstendighetens skyld enn som faktisk relevant informasjon for de fleste lesere.

Bruken av SQL_CALC_FOUND_ROWS og FOUND_ROWS() har noen fallgruver når de brukes i UNION-spørringer, siden LIMIT-setninger kan brukes flere steder, og kan påvirke både individuelle SELECT-setninger i UNION og den generelle UNION resultat som regel. Formålet med SQL_CALC_FOUND_ROWS for UNION er å telle antall rader som vil bli returnert uten en global LIMIT . Derfor bør betingelsene for bruk av SQL_CALC_FOUND_ROWS med UNION-spørringer angis:

  • SQL_CALC_FOUND_ROWS nøkkelordet må vises i det første SELECT-setning ;
  • Verdien av FOUND_ROWS() vil bare være nøyaktig hvis UNION ALL brukes. Hvis UNION er spesifisert uten ALL, oppstår duplikat-eliminering og verdien av FOUND_ROWS() vil bare være omtrentlig;
  • Hvis LIMIT ikke er til stede i UNION, ignoreres SQL_CALC_FOUND_ROWS og antall rader i den midlertidige tabellen som er opprettet for å utføre UNION, returneres.

De manus vil tillate deg å vise ikke bare piler på " forrige side"Og" neste side", som i artikkelen, men også, hvis ønskelig, vil bidra til å vise en konsistent liste over lenker til alle sidene på nettstedet. Du kan se hvordan det ser ut på nettsiden min - bare gå ned til hjemmeside nettstedet.

Bruk phpmyadmin (eller sql), lag en tabell (navnet er opp til deg, jeg kalte opt) med to felt. Ring den første felt-ID-en, den andre str. Begge feltene må ha numerisk type(int), tilordne auto_increment til id-feltet. Dette bordet vil lagre numerisk verdi(i str-feltet), som bestemmer antall innlegg som vises på én side.

Alt annet er enkelt. Vi gjør en forespørsel og henter denne numeriske verdien, legger den inn i en variabel, for eksempel $num . Vi bestemmer det totale antallet innlegg (meldinger) i databasen og legger inn denne verdien i $posts-variabelen. Finn det totale antallet sider på nettstedet ($total) og rund ned. Vi beregner fra hvilket innlegg det er nødvendig å vise meldinger (innlegg) på denne siden ($start). Vi sender en forespørsel til tabellen med innlegg og begrenser den med en grense ($num), vi spesifiserer også parameteren ($start) som utdataene til poster vil begynne fra. Nå gjenstår det bare å ordne lenkene til de relevante sidene deretter, og vips, du er klar. Mer Detaljert beskrivelse manus kan sees direkte i koden.

$result77 = mysql_query("SELECT str FROM opt", $db); $myrow77 = mysql_fetch_array($result77); // antall innlegg på én side $num = $myrow77["str"]; // Trekk ut fra URL nåværende side@$page = $_GET["side"]; // Bestem det totale antallet meldinger i databasen $result00 = mysql_query("SELECT COUNT(*) FROM posti"); $temp = mysql_fetch_array($result00); $posts = $temp; // Finn det totale antallet sider $total = (($posts - 1) / $num) + 1; $total = intervall($total); // runde gjeldende side $page = intval($page); // Hvis $page-variabelen er mindre enn 0 eller tom // tilordne $page 1 // Og hvis verdien av $page er høyere enn $total, // tilordne $page verdien av variabelen $total if(empty($ side) eller $side< 0) $page = 1; if($page >$total) $side = $total; // Beregn fra hvilket tall // meldinger som skal vises $start = $side * $num - $num; // Velg $num innlegg fra tallet $start // -----MINI INNLEGG----- $result = mysql_query("VELG * FRA posti ORDER BY date DESC LIMIT $start, $num ",$db ) ;

//Vis alle innlegg i en loop

// Sjekk om tilbakepiler er nødvendig hvis ($page != 1) $pervpage = "Første forrige"; // Sjekk om fremoverpiler er nødvendig hvis ($page != $total) $nextpage = "Neste Siste"; // Finn de to nærmeste sidene fra begge kanter, hvis de finnes 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.$nesteside;

Fordelen med denne navigasjonen er at alle sidene på nettstedet kan lokaliseres innen 3 klikk fra hovedsiden. Denne funksjonen kan være nyttig, for eksempel når du arbeider med SAPE-tjenesten.

Problemet med å implementere sidenavigering står ofte overfor nybegynnere PHP-programmerere. Å dele opp voluminøs tekst i separate sider brukes i mange nettapplikasjoner, fra gjestebøker og fora til ulike kataloger. La oss
La oss løse dette problemet.
Så hva trenger vi for å implementere sidenavigering? La oss for eksempel ta en gjestebok som inneholder flere hundre meldinger, der du vil vise X meldinger på siden.
La oss se på problemet mer spesifikt. Brukermeldinger lagres i en database post med følgende struktur:

  • id – meldingsnummer,
  • tekst – meldingstekst,
  • navn – forfatterens navn,
  • tid – skapelsestid.

Som et resultat må vi få X-meldinger til siden, og også organisere praktisk navigering, for eksempel slik:

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

hvor 4 er gjeldende side. For å spore gjeldende side, bruker vi parameteren side, sendt via URL. For eksempel:

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

Her er X sidetallet (la for eksempel X være lik 25).

Nå, etter denne korte introduksjonen, kan vi begynne selve implementeringen.

// Etabler en tilkobling til databasen
inkludere "config.php" ;
// Variabelen lagrer antall meldinger som vises på siden
$num = 25 ;
// Hent den gjeldende siden fra URL-en
$side = $_GET ["side" ];
// Bestem det totale antallet meldinger i databasen
$result = mysql_query ("VELG ANTALL(*) FRA innlegg" );
$posts = mysql_result($result, 0);
// Finn det totale antallet sider
$total = intervall (($posts - 1 ) / $num ) + 1 ;
// Bestem begynnelsen av meldinger for gjeldende side
$side = intervall($side);
// Hvis $side er mindre enn én eller negativ
// gå til første side
// Og hvis den er for stor, gå til den siste
if(empty($page ) eller $page< 0 ) $page = 1 ;
if($side > $total ) $side = $total ;
// Regn ut fra hvilket tall
// meldinger skal vises
$start = $side * $num - $num ;
// Velg $num meldinger fra nummer $start
$result = mysql_query ("VELG * FRA post LIMIT $start, $num" );
// I en løkke overfører vi spørringsresultatene til $postrow-arrayen
while ($postrow = mysql_fetch_array ($result))
?>

Dette fullfører den første delen. Todimensjonal matrise postrow lagrer alle feltene i posttabellen som er nødvendige for å vise siden. Her er et eksempel på hvordan du kan organisere meldingsutdata.

ekko "

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


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

Nå må vi organisere navigasjonen. Vi formulerer komponentene i fremtidig navigasjon.
Vi vil plassere pilkodene «til begynnelsen» og «tilbake» i én variabel, og vi vil også gjøre det samme med pilene «til slutten» og «fremover».

// Sjekk om tilbakepiler er nødvendig
if ($side != 1 ) $pervpage = "<<
. ($side - 1) . ">< " ;
// Sjekk om fremoverpiler er nødvendig
if ($page != $total ) $nextpage = " ">>
. $totalt. ">>>" ;

// Finn de to nærmeste sidene fra begge kanter, hvis de finnes
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 meny
echo $pervpage . $page2left . $page1venstre . " ". $side ."" . $page1right . $page2right . $nesteside ;

God kveld brukere. Du har sikkert møttes ofte sidenavigering på nettsteder. I denne leksjonen vil vi lære hvordan du lager slik side-for-side-navigering.

Som vanlig legger jeg ut en demoversjon og kildemateriale for denne leksjonen. I demoversjonen kan du se sidenavigasjonen som vi nå skal gjøre.

For denne opplæringen trenger vi en database, en kjørende lokal server, et navigasjonsskript og din tålmodighet.

Trinn 1. Database

Først av alt må vi lage en database og en bruker. Og lag også en tabell og fyll den med informasjon. I mitt eksempel kalles databasen navigasjon, og tabellen heter nyheter.

Se skjermbildet nedenfor for tabellstrukturen:

Tabellen består av 3 felt − id, tittel, tekst.

Trinn 2. Koble til databasen

Nå må vi skrive en tilkobling til databasen. For å gjøre dette opprettet jeg en ny fil og kalte den cfg.php. I denne filen skrev jeg følgende kode:

Det er ikke noe komplisert i denne koden. Vi skrev en vanlig tilkobling til databasen og spesifiserte en betingelse, hvis noe plutselig går galt, får vi en feil. Vi spesifiserte også databasekodingen - utf8.

Trinn 3. Utdata informasjon fra databasen

La oss nå lage en fil og kalle den index.php. Dette vil være vår hovedfil. Den vil vise poster og her vil vi lage sidenavigasjon. Ikke glem å arkivere index.php koble til filen cfg.php. For å gjøre dette, skriv følgende kode et sted på begynnelsen av siden:

For å vise informasjon fra databasen skrev jeg i filen index.php her er koden:

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

Det er heller ikke noe uvanlig i denne koden. Vi har valgt ut all informasjon fra tabellen nyheter og sende den ut ved hjelp av en sløyfe gjør mens.

Trinn 4. Første del av manuset

Nå som vi har all informasjonen vist, kan vi bruke den første delen av skriptet. For å gjøre dette i filen index.php Før du prøver informasjonen, sett inn koden:

$num = 5; $side = $_GET["side"]; $result00 = mysql_query("VELG ANTALL(*) FRA nyheter"); $temp = mysql_fetch_array($result00); $posts = $temp; $total = (($posts - 1) / $num) + 1; $total = intervall($total); $side = intervall($side); if(empty($page) eller $page $total) $page = $total; $start = $side * $num - $num;

Denne linjen $num = 5; er ansvarlig for antall artikler på siden. I stedet for tallet 5 kan du sette din egen verdi.
Du må også endre selve utvalgsinformasjonen litt og legge til følgende:

$query = mysql_query("VELG * FRA nyheter BESTILLE ETTER ID-LIMIT $start, $num");

Koden vår skal nå se slik ut:

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

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

Trinn 5. Vis navigasjonen

I dette trinnet må vi vise selve navigasjonen, som vil se ut 1 | 2 | Neste | Siste. For å gjøre dette i filen index.php under den forrige koden åpne php-koder 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 menyen hvis det er mer enn é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.$nesteside; ekko "

Trinn 6. Resultat av utført arbeid

Det er alt, denne leksjonen er over. Takk for din oppmerksomhet!

Du kan se hele koden for alle sidene og skriptkoden i kildene. Du kan laste ned kildekoden fra lenken i begynnelsen av leksjonen helt gratis og uten reklame.

Leksjonen ble forberedt for deg av stedets team.