Kako postaviti pametne telefone i računala. Informativni portal
  • Dom
  • Greške
  • Predmemorija preglednika (PHP, Javascript). Jednostavan i učinkovit PHP sustav za predmemoriju

Predmemorija preglednika (PHP, Javascript). Jednostavan i učinkovit PHP sustav za predmemoriju

U prethodnom članku o web tehnologijama spomenuli smo koristan članak Caching in HTTP (u daljnjem tekstu: "Članak s nomagic.ru"). O članku smo, međutim, imali pitanja, a rasprava je tu zamrla, pa smo sve odgovore morali tražiti sami. Pitanja, naime, nisu posebno vezana uz članak – gomilaju se već nekoliko godina. Umorni su od toga da su neriješeni, a članak mi je samo dao razlog da aktivnije tražim rješenja.

Alati

Prvo pitanje je kako vidjeti HTTP zaglavlja zahtjeva preglednika i odgovora poslužitelja? Autor članka s nomagic.ru preporučuje korištenje "Web Developer Tools" u Firefoxu za tu svrhu i neku vrstu blatne "DevToolbar" za IE. Ruka je ispružila ruku da klikne na vezu, ali je visjela u zraku:

1) web programer Već imamo alate za FF, a ne postoji alat za pregled HTTP zaglavlja, čak je i DOM inspektor iz nekog razloga uklonjen u verziji 3!

3) I potpuno sumorna misao: dobro, recimo za FF imamo LiveHTTPHeaders; s IE - iznenada vam se posreći; Pa, što je s Operom? A Google chrome?.. Što sad jurimo po vrtu?

Zašto ne biste prikazali sva HTTP zaglavlja izravno na web mjestu koristeći PHP? Doista postoji varijable okoline, varijable za rad s poslužiteljem i sve to. Odnosno, točno se zna što postoji, na primjer, $_SERVER["HTTP_HOST"] i HTTP_REFERER (koristimo ga na svakoj stranici). Sve ostalo treba dodati. http_- ovdje su zaglavlja zahtjeva. Štoviše, PHP za to ima posebnu funkciju getallheaders(). Ili apache_request_headers(). I apache_response_headers(). Da. Tako možete prikazati sva HTTP zaglavlja. Naizgled. No, čekao nas je težak udarac ispod pojasa i 15 minuta agonije, čiji je rezultat bio otkriće: na našem hostingu PHP je instaliran kao cgi (ne kao Apache modul) && u ovoj konfiguraciji, sve ove ... funkcije zaglavlja () ne rade!

Pokretanje skripte sa echo phpinfo() i kratko pregledavajući rezultat, otkrivamo da su zaglavlja HTTP zahtjeva koja tražimo u nizu $_ENV(i nigdje drugdje). U redu, _env je _env. Ali ima puno smeća (trenutačno nam je suvišno), pa stvaramo novi niz $varrvis i pažljivo odrežite više ili manje potrebne komade iz _env tamo:

Foreach($_ENV kao $ke=>$va) ( if (preg_match("/^HTTP\_/i",$ke) && !preg_match("/COOKIE/i",$ke)) $varrvis["$ ke"]=$va;)

Ali da bismo dobili zaglavlja odgovora našeg poslužitelja - pa, konačno, ništa, osim funkcije headers_list(). I samo ona zaglavlja koja ćemo sami poslati u PHP skriptu koristeći funkciju Zaglavlje(). U osnovi funkcija headers_list() treba pokrenuti nakon što su sva zaglavlja napisana. Napravili smo ovako nešto, iako, najvjerojatnije, za ovo mjesto (mjesto na kojem su eksperimenti provedeni) nije važno, jer se koristi posvuda ob_start("ob_gzhandler"). Na kraju testiranih skripti dodajte sljedeću konstrukciju:

Foreach(headers_list() kao $ke=>$va) ( $varrvis[$ke]=$va; )

A mi nadopunjujemo naš niz zaglavlja odgovorima poslužitelja. I između Zahtjeva i Odgovora, radi čitljivosti, umetnite redak:

$varrvis["Odgovor"]="===============================";

Ostaje napisati na samom kraju testiranih skripti print_r($varrvis)- a zatim veselo listati stranice stranice u svim dostupnim preglednicima, diveći se HTTP zaglavljima.

HTTP caching s Apache uputama

Članak s nomagic.ru ističe dva izvora uputa za predmemoriju: Apache konfiguracijske datoteke (http.conf && .htacces) i samu PHP skriptu s naredbama header("Pragma: no-cache"). Ali postoji i treći izvor - može se otkriti jednostavnim eksperimentom:

1) pisati (dekomentirati) u httpd.conf(Apache 1.3.39) redovi:

LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so AddModule mod_expires.c AddModule mod_headers.c

2) u mapi naše stranice u .htaccess dodaj upute:

Zaglavlje dodaj Cache-Control "javno" ExpiresActive On ExpiresDefault "pristup plus 1 sat"

3) napisati jednostavnu skriptu pi.php iz dva reda:

4) otvorite pi.php stranicu u Firefoxu i pogledajte je u LiveHTTPHeaders (Naš PHP "alat" može prikazati samo zaglavlja poslana funkcijom header(), koje još ne koristimo.) sljedeće linije vezane za predmemoriju:

Kontrola predmemorije: bez pohrane, bez predmemorije, mora se ponovno potvrditi, naknadna provjera=0, pretprovjera=0 Istječe: čet, 19. studenog 1981. 08:52:00 GMT Pragma: bez predmemorije

Voila. I nema potrebe za bilo kakvom Wikipedijom - ovo su naslovi koji ubijaju keširanje. Dolaze iz trećeg izvora, datoteke php.ini. Prema zadanim postavkama, prilikom instalacije PHP-a, sadrži, posebno, sljedeću instrukciju:

session.cache_limiter = nocache

To je ono što uzrokuje da PHP šalje zaglavlja protiv predmemorije pod određenim uvjetima (na primjer, kada se koristi funkcija session_register()). Malo smo se, naravno, varali, prilagođavajući situaciju ovim uvjetima. Ali tko može jamčiti da nikada neće koristiti funkciju registar_sjednice()? Da, općenito, stvari su prilično loše bez toga: uklonite prvi redak iz skripte pi.php (ostavite samo echo phpinfo();) - također nije dobro:

I to je sve što Apacheove upute za cachiranje daju u kombinaciji s "session.cache_limiter=nocache" u php.ini. Nedostaje najvažniji naslov - Zadnja promjena(datum zadnje izmjene stranice), bez kojeg je nemoguće pravilno postaviti niti ispravno uništiti caching u pregledniku.

Najzabavniji rezultat dobiva se ako "povučete papigu za obje noge odjednom" - upišite u php.ini "session.cache_limiter=private" (morate ponovno pokrenuti Apache) i ostavite redak session_register("var1") u skripta:

Kontrola predmemorije: privatno, max-age=300, pre-check=300 Istječe: čet, 19. studenog 1981. 08:52:00 GMT Zadnja izmjena: pon, 6. srpnja 2009. 15:13:40 GMT

Pojavljuje se Zadnja promjena, koji pokazuje vrijeme kada je php skripta zadnji put modificirana, i Kontrola predmemorije proturječi Istječe. Ponašanje preglednika bit će nepredvidivo.

Ispravno HTTP caching

U posljednjim naslovima koje smo dobili tijekom eksperimenta, nedosljednost, općenito, nije nimalo fatalna: preglednici nisu vidjeli ništa slično, prilično su "otporni na buku" na takve stvari. Najveći problem je samo Zadnja promjena, koji je potreban i korisnicima (preglednicima) i tražilicama. Jasno je da se datum izmjene PHP datoteke ne može koristiti za to - jer stvarni sadržaj stranice možda uopće nije povezan s tim datumom: obično se sadržaj stranice preuzima iz baze podataka, a datum odatle se također mora izvući njegova modifikacija (od DB).

Ako se radi o određenom članku s naše stranice, jednostavno uzimamo datum trenutnog unosa iz polja `datrec` u tablici `članci`. Ako je ovo popis članaka (na glavnoj stranici stranice), tražimo najveći datum svih unosa koristeći formulu "odaberi max(`datrec`) iz `članaka`" - to će biti datum posljednja izmjena stranice, koju ćemo proslijediti u naslovu Zadnja promjena.

Postoje još dvije "kontrolne točke" sadržaja implementirane pomoću HTTP zaglavlja:

1) Etag– hash sadržaja stranice, dobiven, na primjer, korištenjem funkcije md5(tekst_stranice);

2) dužina sadržaja- ukupna duljina teksta poslanog pregledniku kao odgovor na njegov zahtjev.

Ne možemo koristiti dužina sadržaja, jer se ovaj parametar stalno mijenja: u desnom stupcu svake stranice imamo podsjetnik da je ovo još uvijek stranica reklamnih novina Delovaya Nedelya, popis proizvoda najnovijeg broja novina. Ovaj popis je prilično velik, tako da se samo mali dio popisa prikazuje na stranici, odabranoj nasumično.

Kako, pitate, koristimo Etag– i on se onda stalno nasumično mijenja? I vrlo je jednostavno: ne uključujemo varijabilni dio stranice u hash, već sastavljamo hash samo "na temelju materijala baze podataka članaka". Zašto ne možete učiniti isto sa dužina sadržaja? Da zato dužina sadržaja preglednik može lako provjeriti (IE radi upravo to - šalje natrag poslužitelju stvarnu duljinu primljenog sadržaja). A hash se može napisati na bilo koji način (glavno je da se mijenja kada se prati dio stranice), preglednik ne zna koji algoritam koristimo i prisiljen je jednostavno prihvatiti naš Etag na vjeru.

Koristimo dvije metode raspršivanja:

1) u slučaju popisa tekstova dobivenih iz mnogih redova tablice, kreiramo Etag* prema formuli $etag=md5($list);

2) u jednostavnijem slučaju (iz tablice se dohvaća samo jedan zapis), mysql radi tako što upitu dodamo dodatnu vrijednost: "odaberi `id`, `naslov`, `tekst`, `autor`, `datrec `, old_password(concat(`naslov`,`tekst`,`autor`)) kao `etag` iz `članaka`...".

Kada šaljete zaglavlja s funkcijom header(), morate biti sigurni da se te radnje izvode prije slanje sadržaja pregledniku na neki način (putem echo-a, ispisa PHP-a ili jednostavnog HTML koda). To jest, prvo, cijeli dio koji se provjerava stavlja se u varijablu, the Etag*, šalju se sva zaglavlja i tek tada se može prikazati sadržaj. Osim ako, naravno, niste napisali ob_start("ob_gzhandler") na vrhu stranice. Upravo smo to napisali, pa naslove šaljemo bilo kada i bilo kada. Ovaj ob_gzhandler također vam omogućuje da dobijete sav sadržaj poslan u preglednik odjednom - pomoću funkcije ob_get_contents(), kao i pravu dužinu sadržaja (za naslov dužina sadržaja) - funkcija ob_get_length(). Mi, kao što je već spomenuto, ne možemo koristiti na ovoj stranici svi sadržaj stranice za formiranje ovih naslova. Ali na drugim stranicama - sasvim.

304 Nije izmijenjeno

Stoga klijentima šaljemo točan datum izmjene stranice i Etag. Klijenti imaju razumijevanja - šalju zaglavlja u sljedećim zahtjevima na ovu stranicu Ako-Modificirano-Od i Ako-Nema-Match, što se i sami možete uvjeriti na samom dnu bilo kojeg našeg članka (nakon pritiska tipke F5, naravno). Ali željeni rezultat nije postignut: poslužitelj redovito šalje zaglavlje kao odgovor na sve zahtjeve preglednika HTTP/1.x 200 U redu, i ne 304 . Naš "alat" ne prikazuje zaglavlja "200 OK" jer ih ne generiramo s funkcijom header().

Zaglavlje 304 može se vidjeti u izobilju kroz LiveHTTPHeaders - u slikovnim datotekama, Javascript, css i jednostavnim HTML stranicama. Apache sam šalje ovo zaglavlje, i to bez ikakvih naših trikova s ​​modulom headers.so i bez dodatnih uputa poput "ExpiresActive On". Ali ne za stranice koje generira PHP.

Slanje zaglavlja u preglednik smo sami unijeli u PHP skriptu, te sami moramo provjeriti prisutnost ili odsutnost provjere valjanosti naknadnih zahtjeva preglednika, a zatim sami usporediti kontrolne parametre i, ovisno o rezultatu, poslati pregledniku a Zaglavlje 200 ili 304. Točnije, PHP zaglavlje 200 uvijek se samo šalje, samo trebamo izračunati situaciju potrebe 304. To radimo u glavnoj konfiguracijskoj datoteci svih web-mjesta configbase.php.

Teškoća dobivanja informacija o zaglavljima je u tome što na jednom hostingu PHP radi kao cgi, a na drugom kao Apache modul, tako da prvo morate provjeriti prisutnost varijabli u "superglobalnim" nizovima Env i poslužitelju, i ovisno o rezultatu, stvorite vezu na odgovarajući niz:

$h304="HTTP/1.x 304 nije promijenjen"; $match=""; $since=""; $varr=niz(); $varrvis=niz(); if (array_key_exists("HTTP_HOST",$_ENV)) $varr =& $_ENV; if (array_key_exists("HTTP_HOST",$_SERVER)) $varr =& $_SERVER; if (isset($varr["HTTP_IF_NONE_MATCH"])) $match=$varr["HTTP_IF_NONE_MATCH"]; $match=trim(strval($match)); if (isset($varr["HTTP_IF_MODIFIED_SINCE"])) $since=$varr["HTTP_IF_MODIFIED_SINCE"]; $since=eksplodirati(";",$od); $since=strtotime(trim($od));

Pretposljednji red je potreban zbog IE-a, koji također šalje duljinu stranice u zaglavlju IF_MODIFIED_SINCE: "Pet, 03. srpnja 2009. 15:42:30 GMT; dužina=20994" - iz ovog zaglavlja izrezali smo sve što može biti nakon točke zarez. Zatim stvaramo niz HTTP zaglavlja neovisno o hostu:

Foreach($varr kao $ke=>$va) ( if (preg_match("/^HTTP\_/i",$ke) && !preg_match("/COOKIE/i",$ke)) $varrvis["$ ke"]=$va; ) $varrvis["Odgovor"]="=============================";

Pa, i glavni fragment predmemorije, jezgra cijelog našeg sustava, smješten unutar PHP stranica (gdje je $dat vrijeme iz mysql tablice, prevedeno u sekunde pomoću funkcije strtotime):

Zaglavlje("Etag: $etag"); header("Kontrola predmemorije: privatno, max-dob=0"); header("Ističe: ".gmdate("r")." GMT"); header("Veza: Održavaj u životu"); header("Keep-Alive: timeout=5, max=100"); if ($since==$dat) ( if (!$match || $match==$etag)( $varrvis=$h304; uključi "bottom.php"; header($h304); header("Veza: Zatvori "); izađi; ) ) else ( header("Zadnja izmjena: ".gmdate("r", $dat)." GMT"); )

Sustav radi ispravno u svim preglednicima spomenutim u ovom članku: sprema se po potrebi i šalje nove informacije pregledniku, ako ih ima. Na primjer, ako nakon otvaranja glavne stranice stranice (s popisom članaka) pritisnete F5 (ne u Operi! :-), na dnu stranice možete vidjeti dugo očekivani naslov 304 (u Operi se također može vidjeti ako na ovu stranicu dođete klikom na link na drugoj stranici stranice). Ako je naslov članka promijenjen ili je, na primjer, dodan novi članak, skripta će, nakon što od preglednika primi zahtjev za provjeru valjanosti, otkriti promjenu podataka i poslati pregledniku novi sadržaj stranice, a ne naslov 304 .

U ljudskom smislu, ono što radimo s ovim naslovima može se sažeti na sljedeći način:

1) pregledniku (uglavnom bilo kojem klijentu) šaljemo dvije identifikacijske oznake: vrijeme posljednje promjene sadržaja stranice i hash stranice (kontrolni zbroj); također šaljemo instrukciju da dopustimo cachiranje samo krajnjem klijentu (Cache-Control: privatno); u istom zaglavlju (max-age=0) kažemo da klijent ne smije zahtijevati novi sadržaj unutar 0 sekundi (odnosno, uvijek ga treba tražiti); u sljedećem naslovu (Expires) kažemo klijentu isto: termin "spaljivanja" relevantnost stranice istječe odmah, upravo sada;

2) preglednik poslušno dodaje stranicu u svoju predmemoriju, zajedno sa slikama i css datotekama; pri sljedećim pozivima na stranicu, preglednik pita poslužitelj je li se promijenio datum (IF_MODIFIED_SINCE) i, ponekad, kontrolni zbroj (IF_NONE_MATCH) - na primjer, ne pita za IE kontrolni zbroj;

3) ako se datum promijenio, provjeravamo da li je postojao zahtjev za kontrolnu sumu od preglednika, a ako jest, provjeravamo i njegovu promjenu; ako se ništa nije promijenilo, šaljemo zaglavlje pregledniku 304 ; ako se promijenilo - nemojte slati 304 (a sam PHP šalje 200 OK);

Da, i još jedan detalj za naš "alat": prvo zaglavlje (HTTP status) iz nekog razloga ne dohvaća funkcija headers_list(). Kad on 200 , nije jako bitno, ali 304 Htio bih vidjeti (kako bih se uvjerio da naš sustav za predmemoriju radi). Stoga ovaj naslov morate ručno "obojiti" u niz naslova u retku

$varrvis=$h304;,

a zatim za sve ostale koje prima funkcija headers_list() zaglavlja povećavaju indeks za jedan ($ke+1):

Foreach(headers_list() kao $ke=>$va) ( $varrvis[$ke+1]=$va; )

Posljednja nijansa. Kako vidjeti naslov 304 u pregledniku, ako je preglednik primio ovo zaglavlje od poslužitelja, a nije primio nikakav sadržaj stranice (stranica se ne bi trebala mijenjati na ekranu)? Neka ovo bude naša mala tajna.

© 2009, Business Week, Mihail Gutentog

501 . SlipkeR

Hvala) sve je jasno i razumljivo napisano) autoru ATP)

Moderni preglednici često koriste lokalnu predmemoriju u svom radu. Što to znači? To znači da preglednik, nakon što je od poslužitelja primio html dokument, sliku ili neki drugi resurs, smješta ga u svoju lokalnu predmemoriju (drugim riječima, upisuje primljeni resurs na tvrdi disk korisničkog stroja) i, na naknadne zahtjeve, ne pristupa takvom resursu poslužitelju, ali prima resurs iz lokalne predmemorije.

Ovaj algoritam preglednika dramatično povećava brzinu učitavanja html dokumenata. Budući da je resurs već učitan i, kao rezultat toga, nalazi se u lokalnoj predmemoriji, tada vrijeme pristupa nije određeno propusnošću komunikacijskog kanala (na primjer, modemske veze), već brzinom tvrdog voziti.

No, uz prednosti, ova metoda stvara i niz problema. Konkretno, većina web programera početnika susreće se s istim problemom kada razvijaju dinamičke stranice. Bit ovog problema leži u činjenici da umjesto ponovne prijave na poslužitelj za stranicu koja pokreće skriptu na poslužitelju koja mijenja neke informacije, preglednik pristupa lokalnoj predmemoriji. I kao rezultat, na primjer, tri poziva, ne postoje tri izmjene informacija koje se nalaze na poslužitelju, već samo jedna.

Kako bi natjerao preglednik svaki put da zatraži stranicu na poslužitelju, potrebno je zabraniti pregledniku da unese ovaj resurs u predmemoriju. Sljedeće su najčešće metode za onemogućavanje ili zaobilaženje predmemorije.

Nova generacija URL-ova

Recimo da traženi resurs ima sljedeći url: test.html?id=7. Kao što možete vidjeti iz url-a, jedan parametar mu se prosljeđuje. Dodajmo, na primjer, koristeći JavaScript, još jedan parametar URL-u i učinimo njegovu vrijednost slučajnim brojem. Kao rezultat, url će izgledati ovako: test.html?id=7&rnd=0.6700820127538827. Svaki put iznova će se generirati slučajni parametar. Ispod je popis koji pokazuje ovaj pristup:

Nova generacija URL-ova test link

Svaki put kada će se rezultat takvog zahtjeva spremiti u predmemoriju, ali budući da se predmemoriranje izvodi na cijelom url-u, svaki put će se dobiti novi url i preglednik će biti prisiljen zatražiti resurs od poslužitelja, budući da su url-ovi dvaju zahtjevi se neće točno podudarati.
Polja zaglavlja

Također možete upravljati cachiranjem sa strane poslužitelja. Da biste to učinili, resurs poslan pregledniku popraćen je poljima zaglavlja. Detaljan opis polja zaglavlja može se pronaći u Rfc 2068, koji opisuje HTTP 1.1 protokol.

Istječe polje zaglavlja

Vrijednost ovog zaglavlja je datum nakon kojeg će sadržaj izvora postati zastario. Ako korisnik pristupi resursu nakon tog datuma, preglednik bi trebao zatražiti resurs od poslužitelja, a ne iz lokalne predmemorije.

Ako polje >Ističe< содержит дату, прошедшую, по отношению к текущей, то при следующем обращении к ресурсу браузер будет вынужден снова обратиться к серверу. Это произойдет вследствие того, что либо документ не будет занесен в кэш — как уже устаревший, либо при обращении к кэшу браузер определит, что документ уже устарел. Следующий листинг на PHP демонстрирует использование заголовка Expires:

Polje zaglavlja Last-Modified

Vrijednost ovog zaglavlja je datum posljednjeg ažuriranja resursa. Većina modernih preglednika koristi sljedeći algoritam ako je resurs već u lokalnoj predmemoriji:

* zahtijeva od poslužitelja datum posljednjeg ažuriranja resursa
* uspoređuje primljeni datum i datum resursa u lokalnoj predmemoriji
* ako je resurs na poslužitelju noviji od resursa u predmemoriji, resurs se traži od poslužitelja

Ako resurs koji se nalazi na poslužitelju sadrži trenutni datum u ovom polju, preglednik će svaki put tražiti resurs od poslužitelja, a ne iz lokalne predmemorije. Sljedeći popis pokazuje korištenje polja zaglavlja Last-Modified:

zaglavlje ("Posljednja izmjena: " . gmdate("D, d M Y H:i:s") . " GMT");

Polja zaglavlja Cache-Control i Pragma

I na kraju, polja zaglavlja koja su izravno odgovorna za predmemoriju resursa. Polje Definiran je u Rfc 1945, koji opisuje HTTP 1.0 protokol. Ovo polje je zastarjelo, ali ga je u nekim slučajevima potrebno koristiti. Konkretno, neki proxy poslužitelji ne obrađuju ispravno zahtjeve za resurse koji se stalno mijenjaju ako ovo polje zaglavlja nije proslijeđeno zajedno s resursom.

Drugo polje definirano je u Rfc 2068, koji opisuje HTTP 1.1 protokol. Ovo polje zaglavlja omogućuje vam da onemogućite predmemoriju i svaki put kada zatražite resurs od poslužitelja. Sljedeći popis pokazuje upotrebu polja zaglavlja Cache-Control i Pragma za onemogućavanje predmemoriranja:

header("Kontrola predmemorije: nema predmemorije, mora se ponovno potvrditi"); header("Pragma: nema predmemorije");

Dobar loš

U dobra stara vremena, stvaranje web stranica bilo je jednostavno kao i upisivanje nekoliko HTML-pages, slanje web stranica u preglednik je jednostavno datoteka koju šalje web poslužitelj. Posjetitelji web-mjesta mogli su vidjeti ove male stranice s cijelim tekstom gotovo trenutno (osim za spore korisnike modema). Nakon što je stranica učitana, preglednik je sprema negdje na lokalnom računalu tako da, ako se stranica ponovo zatraži, može dohvatiti lokalnu verziju iz predmemorije, šaljući samo kratki zahtjev kako bi se uvjerio da stranica na poslužitelju nije t je promijenjeno. Zahtjevi su obrađeni brzo i što učinkovitije, a svi su bili zadovoljni (osim onih koji koriste 9600 baud modeme).

Pojava dinamičkih web stranica promijenila je stvari na gore, učinkovito razbijajući ovaj model posluživanja web stranica zbog dva problema:

  1. Kada poslužitelj primi zahtjev za dinamičkom web-stranicom, izvodi se neka srednja obrada, kao što je raščlanjivanje (parsiranje) skripte od strane motora PHP biti dovršen. To nam daje odgodu prije nego što web poslužitelj počne slati izlaz u preglednik. Za jednostavno PHP-script nije bitan, ali za složeniju aplikaciju, motor PHP može izvršiti mnoge radnje prije nego što stranica bude spremna za slanje. Ovi dodatni koraci rezultiraju primjetnim kašnjenjem između zahtjeva korisnika i stvarnog prikazivanja stranica u njihovim preglednicima.
  2. Tipični web-poslužitelj, kao što je Apache, koristi vrijeme izmjene datoteke kako bi ispravno rekao web-pregledniku stanje predmemorije tražene stranice. Za dinamičke web stranice, zapravo PHP-skripta se može mijenjati samo povremeno, dok se sadržaj koji prikazuje, a možda se nalazi u bazi podataka, često mijenja. Web poslužitelj ne može znati da se baza podataka promijenila, ali ne šalje datum posljednje izmjene. Ako klijent (preglednik) ne dobije nikakvu naznaku koliko dugo su podaci valjani, pretpostavlja da sljedeći put treba zatražiti novu stranicu. Web poslužitelj će uvijek odgovoriti ažuriranom verzijom stranice, bez obzira na to jesu li se podaci promijenili ili ne. Kako bi izbjegli ovaj nedostatak, većina web programera koristi meta oznake ili http-zaglavlja kako bi pregledniku rekli da nikada ne koristi predmemoriranu verziju stranice. Međutim, to negira prirodnu sposobnost web-preglednika da predmemorira web stranice i ima neke značajne nedostatke. Na primjer, sadržaj dinamičke stranice može se mijenjati jednom dnevno, tako da je prednost 24-satnog predmemoriranja stranice očigledna.

Obično je za male PHP aplikacije u redu zanemariti postojanje ovih problema, ali kako se povećava složenost i promet vaše stranice, možete naići na probleme. Međutim, oba se ova problema mogu riješiti, prvi predmemoriranjem na strani poslužitelja, a drugi kontroliranjem predmemorije na strani klijenta iz vaše aplikacije. Pristup koji ćete poduzeti za rješavanje problema ovisit će o vašoj aplikaciji, ali u ovom ćemo poglavlju vidjeti kako možete riješiti oba problema koristeći PHP i neke bibliotečke klase. KRUŠKA.

Kako mogu spriječiti preglednike da spremaju stranicu?

Prije nego što pogledamo tehnike predmemoriranja klijenta i poslužitelja, prvo moramo razumjeti kako spriječiti web preglednike (i proxyje) da uopće spremaju stranice. Glavni način da se to postigne je korištenje HTML meta oznaka:

Umetanjem prošlog datuma u meta oznaku Expires govorite pregledniku da je kopija stranice u predmemoriji uvijek zastarjela. To znači da preglednik nikada ne smije keširati stranicu. Meta oznaka Pragma: bez predmemorije prilično dobro podržana konvencija koju slijedi većina web preglednika. Nakon što pronađu ovu oznaku, obično ne spremaju stranicu (iako nema jamstva, to je samo konvencija).

Ovo zvuči dobro, ali postoje dva problema s korištenjem meta oznaka:

  1. Ako oznaka nije postojala kada je preglednik prvi put zatražio stranicu, ali se pojavi kasnije (na primjer, izmijenili ste datoteku uključivanja pageheader.phpšto je zaglavlje svake web stranice), preglednik će ostati blaženo nesvjestan i koristit će svoju kopiju originala u predmemoriji.
  2. Proxy poslužitelji koji predmemoriraju web-stranice, kao što su zajednički ISP, uopće neće izravno ispitati sadržaj HTML-dokument. Umjesto toga, oslanjaju se samo na web poslužitelj s kojeg su dokumenti došli i protokol http. Drugim riječima, web-preglednik bi mogao misliti da ne bi trebao keširati stranicu, ali proxy poslužitelj između preglednika i vašeg web poslužitelja to vjerojatno ne zna - i nastavit će slati istu zastarjelu stranicu klijentu.

Najbolji pristup je izravno korištenje protokola http koristeći PHP funkciju Zaglavlje(), što je ekvivalentno dvije gore navedene meta oznake:

Korištenjem naslova možemo otići korak dalje Kontrola predmemorije kompatibilan s preglednicima koji podržavaju http 1.1:

Header("Ističe: pon, 26. srpnja 1997. 05:00:00 GMT"); header("Kontrola predmemorije: bez pohrane, bez predmemorije, mora se ponovno potvrditi"); header("Kontrola predmemorije: naknadna provjera=0, pretprovjera=0", FALSE); header("Pragma: nema predmemorije");

To osigurava da nijedan web-preglednik ili posredni proxy neće spremiti stranicu, tako da će posjetitelji uvijek dobiti najnoviju verziju sadržaja. Zapravo, prvo zaglavlje treba biti samostalno, ovo je najbolji način da osigurate da stranica nije predmemorija. Naslovi Kontrola predmemorije i pragma dodano u svrhu "osiguranja". Iako ne rade u svim preglednicima ili proxyjima, uhvatit će neke slučajeve u kojima Istječe ne radi ispravno (na primjer, ako datum na klijentskom računalu nije ispravno postavljen).

Naravno, potpuno eliminiranje cachiranja uvodi probleme o kojima smo raspravljali na početku ovog poglavlja. Sada ćemo razmotriti rješenje ovih problema.

Internet Explorer i predmemorija preuzimanja datoteka

Ako tijekom posluživanja preuzimanja datoteke PHP Skripta koristi zaglavlja kao što su Dispozicija sadržaja: privitak, naziv datoteke=myFile.pdf ili Dispozicija sadržaja: inline, naziv datoteke=mojadatoteka.pdf imat ćete problema s Internet Explorer'ohm ako pregledniku kažete da ne sprema stranicu.

Internet Explorer obrađuje preuzimanje na prilično neobičan način, postavljajući dva zahtjeva web stranici. Prvi zahtjev preuzima datoteku i pohranjuje je u predmemoriju dok se ne izvrši drugi zahtjev (bez spremanja odgovora). Ovaj zahtjev poziva proces prijenosa datoteke do krajnjeg korisnika prema vrsti datoteke (na primjer, start Acrobat Reader ako je datoteka PDF-dokument). To znači da ako pošaljete zaglavlja koja sprječavaju preglednik u predmemoriji stranice, Internet Explorerće izbrisati datoteku između prvog i drugog zahtjeva, ostavljajući krajnjem korisniku ništa. Ako je datoteka koju prenosite PHP-skripta se ne mijenja, jedno od najjednostavnijih rješenja bilo bi uklanjanje zaglavlja "zabrana predmemoriranja" iz skripte.

Ako se datoteka koja se preuzima redovito mijenja (tj. želite da preglednik preuzme najnoviju verziju), trebali biste koristiti zaglavlje Zadnja promjena, o čemu će biti riječi kasnije u ovom poglavlju, i osigurati da se vrijeme izmjene ne mijenja između dva uzastopna zahtjeva. To morate učiniti na način koji ne utječe na korisnike preglednika koji ispravno obrađuju preuzimanja. Jedno rješenje u ovom slučaju bilo bi pohraniti datoteku na vaš web poslužitelj i pružiti jednostavnu vezu do nje, ostavljajući web poslužitelju da za vas izvijesti o zaglavljima predmemorije. Naravno, ovo rješenje možda neće biti prihvatljivo ako se pretpostavlja ovlašteni pristup datoteci, ovo rješenje omogućuje izravno učitavanje spremljene datoteke.

Kako mogu snimiti podatke sa strane poslužitelja za predmemoriju?

Vrijeme je da pogledamo kako možemo smanjiti kašnjenje s predmemoriranjem izlaza na strani poslužitelja. Opći pristup počinje prikazivati ​​stranicu kao i obično, postavljajući upite prema bazi podataka i tako dalje PHP. Međutim, prije slanja rezultata pregledniku, snimamo ga i spremamo gotovu stranicu, na primjer, u datoteku. Na sljedeći zahtjev, PHP-skripta najprije provjerava ima li predmemoriranu verziju stranice. Ako postoji, skripta šalje predmemoriranu verziju pregledniku, čime se eliminira kašnjenje u ponovnom stvaranju stranice.

Nekoliko riječi o keširanju s predlošcima

Kako mogu upravljati cachiranjem na strani klijenta pomoću PHP-a?

Vrijeme je da pogledamo mehanizam koji će nam omogućiti da kontroliramo predmemoriju na strani klijenta pomoću PHP. Ovaj pristup će raditi samo ako koristite PHP u vezi s poslužiteljem Apache, budući da ćemo koristiti funkciju getallheaders() da bi preglednik proslijedio zaglavlja. Ova funkcija radi samo u Apache.

Nova imena funkcija

Ako koristite PHP 4.3.0 s Apache, HTTP zaglavlja dostupna su iz funkcija apache_request_headers() i apache_response_headers(). Funkcija getallheaders() postala je alias za novu funkciju apache_request_headers().

Mehanizam za rad s predmemorijem web preglednika je ponovno http. Brojna zaglavlja uključena su u upućivanje web-preglednika i proxyja da samostalno spremaju stranicu, a situacija je otežana činjenicom da su neka od njih dostupna samo s http 1.1.

Provjera HTTP zaglavlja u vašem pregledniku

Jednostavan, ali vrlo zgodan alat za provjeru zaglavlja zahtjeva i odgovora je LiveHttpHeaders- dodatak pregledniku Mozilla. Morate točno znati koja zaglavlja šalje vaša skripta, posebno kada se bavite zaglavljama u predmemoriji. http.

Radi jednostavnosti, razmotrit ćemo samo HTTP 1.0 predmemorska zaglavlja, naime Istječe, Zadnja promjena i Ako-Modificirano-Od, kao i statusni kod HTTP 304 (nije promijenjeno).

Ostali naslovi dostupni od http 1.1 na primjer Kontrola predmemorije i ETtag, namijenjeni su za pružanje naprednog mehanizma koji se može koristiti zajedno sa stanjem web sesije, drugim riječima, verzija dane stranice prikazana neovlaštenom posjetitelju može se značajno razlikovati od one prikazane ovlaštenom korisniku. Naslovi http 1.1 je izvorno dodan kako bi se takve stranice mogle spremiti u predmemoriju.

Istek stranice

Zaglavlje koje je najlakše koristiti je zaglavlje Isteći, koji postavlja datum (možda u budućnosti) kada će stranica isteći. Do tada, web-pregledniku je dopušteno koristiti predmemoriranu verziju stranice.

Primjer 7.6.php
"; echo "Sada " . gmdate("H:i:s") . " GMT
"; echo "Pogledajte ponovo
"; ?>

Funkcija setIstičešalje zaglavlje http Istječe s budućim vremenom danim u sekundama. Gornji primjer prikazuje trenutačno GMT vrijeme i prikazuje vezu koja vam omogućuje da ponovno odete na stranicu. Korištenjem gumba Osvježi u pregledniku možete reći pregledniku da želite osvježiti predmemoriju. Koristeći vezu, vidjet ćete da se vrijeme mijenja samo jednom svakih 10 sekundi.

Datumi i vremena u HTTP-u

Datumi u HTTP-u uvijek se izračunavaju u odnosu na srednje vrijeme po Greenwichu (GMT). PHP-ova funkcija gmdate() potpuno je ista funkcija kao i date() , osim što automatski kompenzira GMT na temelju sata sustava vašeg poslužitelja i postavki regije.

Kada preglednik naiđe na naslov Istječe, sprema stranicu. Svi sljedeći zahtjevi za stranicu napravljeni prije navedenog vremena isteka koriste predmemoranu verziju stranice i nikakvi zahtjevi se ne upućuju web poslužitelju.

Zaglavlje Istječe uglavnom jednostavan za implementaciju, ali u većini slučajeva, osim ako niste visoko organizirana osoba, ne možete točno znati kada je određena stranica na vašoj web-lokaciji ažurirana. Budući da će preglednik kontaktirati poslužitelj tek nakon što stranica istekne, ne postoji način da se pregledniku kaže da je stranica u njegovoj predmemoriji istekla. Također gubite dio prometa na svojoj web stranici jer preglednik ne kontaktira poslužitelj kada traži stranicu iz predmemorije.

Vrijeme promjene stranice

Praktičnija upotreba zaglavlja Zadnja promjena i Ako-Modificirano-Od dostupno u http 1.0. Tehnički poznato kao izrada uvjetnog GET zahtjeva, vraćate bilo koji sadržaj na temelju uvjeta zaglavlja zahtjeva koji je stigao. Ako-Modificirano-Od.

Kada koristite ovu metodu, morate poslati zaglavlje Zadnja promjena svaki put kada se pristupi vašoj PHP skripti. Sljedeći put kada preglednik zatraži stranicu, poslat će zaglavlje Ako-Modificirano-Od A koji sadrži vrijeme do kojeg vaša skripta može odrediti je li stranica ažurirana od posljednjeg zahtjeva. Ako nije, vaša skripta šalje statusni kod HTTP 304 da naznači da se stranica nije promijenila bez prikaza sadržaja stranice.

Postavite vrijeme izmjene datoteke predmemorije ovim redkom: $lastModified = filemtime($cache_file);

Zatim, koristeći vrijeme izmjene cache datoteke, šaljemo zaglavlje Zadnja promjena. Moramo ga poslati za svaku renderiranu stranicu kako bismo natjerali preglednik da nam pošalje zaglavlje Ako-Modificirano-Od sa svakim zahtjevom.

// Vraća HTTP zaglavlje Last-Modified header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastModified) . " GMT");\n \n"; odjek " \n"; odjek " \n"; odjek " \n"; ?>

Ako kombinirate pristup posljednje izmjene vremena s vrijednošću vremena koja je već dostupna u vašoj aplikaciji (na primjer, vrijeme najnovijeg članka vijesti ili vrijeme isteka iz sustava za predmemoriju na strani poslužitelja koje smo vidjeli u posljednjem rješenju) , možete iskoristiti prednost predmemorije web-preglednika i osloboditi kanal za prijenos podataka, štedeći promet informacija sa svoje stranice ako je moguće i poboljšavajući njezinu izvedbu.

Budite oprezni kada testirate bilo kakvo predmemoriranje urađeno u ovom stilu, ako to učinite pogrešno, možete uzrokovati da vaši posjetitelji uvijek imaju zastarjele kopije vaše stranice.

Predmemorija vaših stranica u 5 koraka

Izvornik: Objavljeno u PHP / JavaScript od strane ibzi 17. veljače 2007
Prijevod: Kuzma Feskov ( [e-mail zaštićen],http://kuzma.russofile.ru)

Predmemoriranje vaših stranica može biti lijep i koristan mehanizam, pogotovo ako ih generira PHP i čine puno SQL upita. Čim primijenite predmemoriju, vaš će poslužitelj odmah smanjiti opterećenje i prestati trošiti puno memorije za generiranje stranica - jednostavno će ih učitati iz predmemorije. Pokazat ću vam kako PHP može keširati stranice, a onda možete provesti 5 minuta radeći to.


Razmotrite tehnologiju predmemorije korak po korak:

  1. Kreirajte datoteke u početnom direktoriju .htaccess, start_cache.php, end_cache.php, kao i mapu pod nazivom cache_files.
  2. Mapa cache_files atributi moraju biti postavljeni 777 .
  3. Iznutra .htaccess datoteku, napišite sljedeće retke: php_value auto_prepend_file /home/username/public_html/start_cache.php php_value auto_append_file /home/username/public_html/end_cache.php Red /home/korisničko ime/public_html/ treba zamijeniti stazom do vašeg matičnog imenika.
  4. Na scenarij start_cache.php stavi sljedeći kod:Ne zaboravite popraviti stazu /home/korisničko ime/public_html/ na put do vašeg matičnog imenika.
  5. I stavite sljedeći kod u skriptu end_cache.php:

Sve vaše stranice bit će spremljene u predmemoriju 3600 sekundi = 1 sat. Ovaj parametar možete jednostavno promijeniti u skripti start_cache.php. Predmemorija stranice bit će spremljena u mapu cache_files.

Jasno je da u ovom slučaju atributi 777 predstavljaju definitivno kršenje sigurnosti. S tim u vezi, preporučam da izvadite mapu cahce_files izvan granica public_html, na primjer, postavite jednu razinu gore. To će zatvoriti pristup datotekama korisnika vaše stranice koje se nalaze na njoj, ali ni na koji način neće utjecati na performanse sustava.

Također, ova metoda ima još jedan ozbiljan nedostatak: autor članka cijelu predmemoriju stavlja u jednu mapu, što će, s dovoljnim brojem stranica na vašoj web-lokaciji, uzrokovati problem, na primjer, na Unix sustavima postoji dovoljno usporavanje performansi kada postoji više od 1000 datoteka u mapi. S tim u vezi, potrebno je napraviti niz promjena u algoritmu i rastaviti datoteke u zasebne podmape unutar mape cache_files. Na primjer, za to koristite prva 3-4 znaka md5 predmemorije.

Za dinamičke resurse sasvim je moguće odabrati vrijeme predmemoriranja od nekoliko (5-10) sekundi ili 1-2 minute, što će već značajno smanjiti opterećenje poslužitelja, ali neće štetiti interaktivnosti web-mjesta.

Za stranice na kojima je interaktivnost posebno važna, možete unijeti iznimke .htaccess, što će im omogućiti stalnu promjenu, a cachiranje se može koristiti za druge stranice.

Regeneracija sadržaja u hodu

Dinamički kreirane, ali statično poslužene stranice, t.j. stranice koje treba prenijeti kao čisto statične (čitati iz datotečnog sustava i zatim prenijeti na zahtjev), ali bi ih trebao dinamički generirati web poslužitelj ako nisu u datotečnom sustavu. Na ovaj način možete imati PHP generirane stranice koje se statički poslužuju osim ako netko (ili planer) ne ukloni statički sadržaj. U tom slučaju sadržaj se ažurira.

To se radi pomoću sljedećeg skupa direktiva:

RewriteCond %(REQUEST_FILENAME) !-s RewriteRule ^page\.html$ page.php

Ovdje zahtjev za page.html uzrokuje interno pokretanje odgovarajuće stranice.php ako stranica.html još uvijek nedostaje ili ima nultu veličinu. Trik je u tome što je page.php normalna PHP skripta koja svoj izlaz upisuje u datoteku page.html pored vlastitog izlaza. Jednom pokretanjem, poslužitelj šalje podatke na page.html. Kada webmaster želi ažurirati sadržaj, jednostavno briše page.html (obično putem cronjoba).

Problem s predmemoriranjem stranica u Internet Exploreru.

U IE-u, kada radite sa zaglavljem "Vary", postoji jedna neugodna pogreška vezana za caching stranice. Problem je riješen dodavanjem sljedećih redaka u .htaccess:

Glavni problem cachiranja je brzina odgovora na zahtjeve glavnim sustavima za pohranu i obradu dolaznih i odlaznih strukturiranih informacija.

Zamislite da trebate brzo prenositi informacije, ali je brzina pristupa podacima iznimno spora. Ili druga situacija: brzina je dobra, ali ima malo dostupne memorije, ili je propusnost nedovoljna, ili faktori procesora i diska ometaju zadatak. U ovom slučaju, caching je jedini izlaz.

Vrste keširanja

Predmemorija (ili predmemorija)- Ovo je neka vrsta međuspremnika u kojem se pohranjuju podaci. Zbog predmemorije, stranica web-mjesta ne izrađuje se ponovno za svakog korisnika. Predmemoriranje omogućuje rad s velikom količinom podataka u najkraćem mogućem vremenu i s ograničenim resursima (poslužitelj i korisnik).

Potrebno je razumjeti da se rad s podacima može obavljati i na strani klijenta i na poslužitelju. Štoviše, poslužiteljska obrada podataka je centralizirana i ima niz nedvojbenih prednosti (osobito za službu podrške).


Postoji nekoliko vrsta predmemorije, predlažemo da razmotrite svaku vrstu, njezine značajke i preporuke za korištenje:
1. Predmemorija preglednika ili predmemorija na strani klijenta
Predstavlja naredbu pregledniku za korištenje kopije u predmemoriji. Rad takvog predmemoriranja temelji se na činjenici da se pri drugom posjetu pregledniku daje zaglavlje 304 Not Modified, a sama stranica ili slika se učitavaju iz lokalne korisničke predmemorije. Ispada da štedite na prometu između preglednika posjetitelja i hostinga stranice. U skladu s tim, stranica vaše stranice počinje se brže učitavati.
1.1 Predmemorija datoteka i slika
Predmemorija preglednika najprikladnija je za web-mjesta koja sadrže veliki broj slika: slika se ne preuzima svaki put kada se stranica otvori, već se jednostavno učitava kroz predmemoriju preglednika.


Ovo je prva razina cachiranja, koja se sastoji u vraćanju zaglavlja "istekao" i zaglavlje "304 Nije izmijenjeno". Najučinkovitije je keširanje 2 tjedna.

Međutim, u ovom slučaju postoji važna nijansa: ako se slika na web-mjestu promijeni, preglednik neće odmah znati za to, već samo ako pričekate istek ili resetirate predmemoriju u samom pregledniku. Ovo nije vrlo učinkovito ako se datoteka stalno mijenja i morate stalno vraćati njezinu trenutnu verziju.

1.2 https keširanje
Posebna zaglavlja poput strict-security. Omogućuje pregledniku da uvijek pristupa odabranoj domeni putem https. To stanje prilično teško sprema i, ako se ova vrsta predmemorije poništi, preglednik će prilično dugo pokušavati učitati stranicu putem https, ignorirajući trenutna zaglavlja.
1.3 CA keširanje
Takozvani pečat tijela za izdavanje certifikata.

Ova vrsta predmemorije smatra se obaveznom ako ne želite da korisnici vaše stranice čekaju da izdavatelj certifikata (a to je određeni poslužitelj koji je odgovoran za valjanost vašeg certifikata) obradi zahtjev iz korisničkog preglednika i potvrdi da vaša stranica je time doista potvrđena.

1.4 Predmemorija stranice
Kada je stranica već generirana, morate stalno pratiti njezinu relevantnost. Da biste to učinili, morate koristiti predmemoriju na strani poslužitelja koja prati vrijeme promjene pojedinih dijelova stranice (ako je stranica izgrađena od mnogo dinamički generiranih blokova). Ovim pristupom u svakom odgovoru poslužitelja postavljaju se posebna zaglavlja koja označavaju vrijeme kada je stranica izmijenjena, a zatim ih korisnikov preglednik šalje kada se stranici stranice ponovno pristupi. Prilikom primanja takvih zaglavlja, poslužitelj može analizirati trenutno stanje stranice (možda ga čak i generirati), ali umjesto sadržaja stranice, vrati zaglavlje "304 Nije izmijenjeno", što za preglednik korisnika znači da možete prikazati stranicu iz predmemorije (preglednika korisnika).

Naravno, moguće je poslati odgovarajuća zaglavlja bez korištenja praćenja predmemorije na strani poslužitelja, ali u ovom slučaju većina korisnika će primiti ažuriranja sadržaja stranice prilično kasno. S ovim pristupom, preglednik ponekad proziva poslužitelj za ažuriranja, ali učestalost i pravila za svaki preglednik konfigurira njegov programer, tako da nema nade da će vaši korisnici primati ažuriranja na vrijeme.

U pravilu, predmemorija je podijeljena prema vrsti korisnika:

Ova podjela je zbog jedinstvenosti sadržaja za svakog ovlaštenog korisnika i zajedničkog sadržaja za gostujuće korisnike. Na većini stranica neovlašteni korisnik ne može mijenjati sadržaj stranice, a samim time i utjecati na njen sadržaj.

Predmemorija preglednika omogućuje vam uštedu prometa i vremena provedenog na učitavanje stranica. Ali da bi postigao učinak uštede, korisnik mora barem jednom posjetiti našu stranicu, što znači da će se opterećenje resursa poslužitelja smanjiti, ali ne značajno.

2. Predmemorija poslužitelja
Predmemoriranje poslužitelja odnosi se na sve vrste predmemorije u kojima se podaci pohranjuju na strani poslužitelja. Ovi podaci nisu dostupni klijentskim preglednicima. Predmemorija se kreira i pohranjuje na bazi jedan-prema-više (mnogi su, u ovom slučaju, klijentski uređaji).

2.1 Predmemorija cijele stranice
Najučinkovitija predmemorija. Zašto je zanimljiv? Njegova najveća prednost je što se stranica vraća gotovo u trenutku pristupa, pa je zbog toga moguće obraditi milijune zahtjeva čak i na najslabijem poslužitelju uz brzinu memorije i uz malo korištenje procesora.

Možda je itko ikada sanjao o web mjestu koje radi brzinom "pinga" ili brže.
Ali ova vrsta predmemorije ima i svoje nedostatke: na primjer, nemogućnost predmemorije stranica za ovlaštenog korisnika ili korisnika čiji sadržaj stranice ovisi o trenutnim korisničkim varijablama.

Koristite ovu predmemoriju ako poslužitelj poznaje sva statička stanja vanjskih podataka, kao što su: uri, get (bez dodatnih parametara), korisnik nije prijavljen – to je, zapravo, idealno stanje stranice za gostujuće korisnike. Uzmite u obzir činjenicu da bi kod takvog cachiranja arhitektura web-mjesta ili aplikacije uvijek trebala obrađivati ​​dolazne zahtjeve na isti način i dati istu vrstu odgovora. Takvo stanje postoji u bilo kojoj aplikaciji ili mjestu, samo ga treba pratiti i primijeniti na predmemoriju.

Predmemorija cijele stranice najčešće se koristi u nekim hitnim slučajevima, dok se predmemorija stranice pohranjuje na unaprijed određeno vrijeme (od 2 minute), tijekom kojeg su odgovori poslužitelja istog tipa (ne dopustite pregledniku da predmemoriju ovo ).

2.2 Predmemoriranje rezultata sastavljanja php datoteka
Postoje i čista kompilacija koda i njegova optimizacija u vrijeme prevođenja (zamjena skripte). Najupečatljiviji primjeri:

Obje vrste predmemorije mogu se koristiti u projektu, ali svaka ima svoje nijanse koje se moraju uzeti u obzir pri pisanju koda.

2.3 Predmemorija pojedinačnih blokova stranice
Ovo je možda najzanimljivija, ali i najsloženija vrsta cachiranja. Ipak, on također može biti učinkovit i najlakši je način objasniti načela predmemoriranja općenito koristeći njegov primjer.
Potrebno je pratiti: stanje tablica, stanje korisničke sesije, treba li isključiti predmemoriranje za POST ili GET zahtjeve (http upit), ovisnost o trenutnoj adresi, postojanost predmemoriranja (kada se promijene prethodni uvjeti) ili njegovu dinamičko prilagođavanje.

Predmemoriranje pojedinačnih blokova stranica bolje je od drugih vrsta predmemoriranja ako trebate, na primjer, smanjiti broj zahtjeva za bazom podataka od stvarnih (ovlaštenih) korisnika. Usput, s točno određenim ovisnostima, radit će čak i učinkovitije od svih sljedećih vrsta predmemorije.

Zašto je ova vrsta keširanja toliko važna? Stvar je u tome da je proširenje baze poslužitelja baze podataka puno teži zadatak od proširenja bazena poslužitelja php dijela stranice. Štoviše, sukobe stanja php predmemorije mnogo je lakše riješiti nego sukobe kada se radi s više baza podataka.

2.4 PHP caching na temelju nedijeljenih resursa
Najprikladniji za standardizaciju upita, dohvaćanje podataka iz zajedničkih resursa, s internim varijablama kojima php resursi pristupaju više puta prilikom generiranja stranice.
2.5 php caching na temelju zajedničkih resursa
Koristite ovu predmemoriju za pohranu serijaliziranih podataka. Na primjer: konfiguracijska datoteka, stanja tablice, popisi datotečnog sustava.
2.6 Mysql predmemorija na temelju predmemorije upita
Ovo je prilično poznata i najčešće obrađena tema. Ipak, želio bih razmotriti specifičnosti rada s vremenskom oznakom i kako možete izbjeći stalno resetiranje predmemorije upita.

Sigurno ste se redovito susreli sa situacijom da trebate poklanjati nove materijale čiji datum objave već dopušta trenutna vremenska oznaka? Jednostavno rečeno,

GDJE show_ts<=UNIX_TIMESTAMP()

Ako u takvim upitima koristite vremensku oznaku koja se stalno mijenja, tada sql predmemorija neće biti samo beskorisna, već čak i štetna, jer će se akumulirati broj predmemorskih upita čiji su podaci zastarjeli u trenutku kada je predmemorija stvorena.

Nudimo sljedeće rješenje:

U pravilu se svaki materijal objavljuje u određenim vremenskim razdobljima. Na primjer, 00:00. Sve što trebate učiniti je stvoriti upit koji će procijeniti tablicu prema maksimalnom datumu, koji je manji od trenutnog.

Nešto kao:

SELECT SQL_NO_CACHE MAX(show_ts) ... WHERE show_ts<=UNIX_TIMESTAMP();

Da, ovaj upit neće biti spremljen u predmemoriju, ali će se svi upiti ovoj tablici spremiti u predmemoriju ako je njihov broj više od jednog. Ova jednostavna operacija uvelike će poboljšati vijek trajanja sql predmemorije.

Ima smisla keširati ove upite ako ima nešto više čitanja iz tablice nego upisivanja.

2.7 Predmemoriranje rezultata rada mysql-a, agregatnih tablica
Postoji pravilo: ažuriranja podataka trebala bi biti mnogo manja od čitanja za njihov povratak.

Odnosno, nema smisla agregirati što će se promijeniti u istom trenutku, dok je relevantnost agregiranih podataka važna.

Što odabrati za agregaciju? Obično je to neka vrsta statističkih podataka o broju zapisa, datumu zadnjeg ažuriranja, autoru zadnjeg ažuriranja i slično.

Zaključak

S obzirom na konstantno opterećenje mreže, bez keširanja nećete moći stvoriti nijedan projekt. Predmemoriranje omogućuje isporuku podataka velikom broju klijenata, uz korištenje minimalnih resursa. U ovom članku razmotrili smo mnoge vrste cachiranja, među kojima, sigurni smo, postoji prikladno rješenje za vaš projekt.

Kako bi se optimizirao rad s mrežom, koristi se mehanizam za spremanje dokumenata jednom primljenih putem HTTP-a u predmemoriju kako bi se mogli ponovno koristiti bez kontaktiranja izvornog poslužitelja. Dokument pohranjen u predmemoriji bit će dostupan sljedeći put kada mu se pristupi, bez iskrcavanja s izvornog poslužitelja, koji je dizajniran za povećanje brzine klijentskog pristupa njemu i smanjenje potrošnje mrežnog prometa.

Postoje dvije vrste predmemorije - lokalni i zajednički. Lokalno je predmemorija pohranjena izravno na disk klijenta, kreirana i kojom upravlja njegov preglednik. Općenito - Proxy cache organizacije ili dobavljača i može se sastojati od jednog ili više proxy poslužitelja. Lokalni cache je prisutan, vjerojatno u svakom pregledniku, značajan dio ljudi koji koriste internet koristi zajednički. A ako se sada mali dio stranica procjenjuje prema potrošnji prometa, onda je brzina preuzimanja važan kriterij koji treba uzeti u obzir pri razvoju vašeg web projekta.
Za dinamičke stranice stvorene kao rezultat pokretanja PHP programa, čini se da je predmemorija štetna. Sadržaj stranice formira se na zahtjev korisnika na temelju nekog izvora podataka. Međutim, keširanje može biti korisno. Upravljajući njime, možete učiniti rad sa svojim poslužiteljem ugodnijim za korisnika tako što ćete dopustiti da se određene stranice učitaju iz predmemorije, čime ćete spriječiti njihovo ponovno učitavanje s vašeg poslužitelja i uštedjeti korisničko vrijeme i promet.

Cache ili ne?

Sposobnost predmemorije stranice određena je dinamičkom prirodom informacija u izvoru podataka. Dakle, potrebu za korištenjem predmemorije određujete sami, na temelju planiranog vijeka trajanja stranice.

Ako govorimo o formiranju selekcije u bazi (na primjer, traženje riječi koju je unio korisnik), tada se takva stranica mora zatražiti od poslužitelja pri svakom pozivu bez korištenja predmemorije, budući da je broj opcija jer je tražene riječi ogromne, a ako imamo posla i s promjenjivim nizom podataka, onda je cachiranje besmisleno. Ili govorimo o formiranju prihvatljivog rasporeda dolaznih posjetitelja (koji se mijenja sa svakim posjetom, odnosno s gotovo svakim pozivom), tada je keširanje jednostavno štetno.

Međutim, ako govorimo o istom grafikonu ali za jučer, onda se preporučuje predmemoriranje, jer se podaci više neće mijenjati i možemo uštedjeti resurse i vrijeme za sebe i korisnika za učitavanje takvih stranica tako što ćemo ih postaviti na lokalnu ili dijeljenu cache. Kao nastavak ove situacije, formiranje grafa nije u realnom vremenu, već po satu. Ovdje možete unaprijed predvidjeti datum isteka "roka valjanosti" generiranih podataka.

Opća načela za spremanje stranica u predmemoriju

PHP program može kontrolirati keširanje rezultata svog rada pružanjem dodatnih polja u zaglavlju HTTP odgovora pozivanjem funkcije Header().
Nekoliko općih izjava koje nisu specifične za PHP programe:

  • Stranice poslane putem POST-a nikada se ne spremaju u predmemoriju.
  • Stranice koje zahtijeva GET i koje sadrže parametre (u URL-u postoji '?') se ne spremaju u predmemoriju osim ako nije drugačije navedeno.

Stoga u većini situacija u program nije potrebno dodavati dodatne upute. Glavne točke na koje treba obratiti pažnju mogu se sažeti u dvije:

  • onemogućiti predmemoriju dokumenata koji se spremaju u predmemoriju prema zadanim postavkama
  • predmemoriranje dokumenata koji prema zadanim postavkama ne podliježu cachiranju.

Onemogućite predmemoriju dokumenata koji se spremaju u predmemoriju prema zadanim postavkama

Ovaj problem nastaje za PHP skripte koje se pozivaju bez parametara ili su indeksi direktorija, ali generiraju podatke osobno za korisnika (na primjer, na temelju kolačića ili korisničkog agenta) ili rade na temelju podataka koji se brzo mijenjaju. Prema HTTP/1.1 specifikaciji, možemo upravljati sljedećim poljima:

Istječe
Određuje datum isteka dokumenta. Postavljanje u prošlost određuje je li predmemorija onemogućena za ovu stranicu.

Kontrola predmemorije: bez predmemorije
Upravljanje predmemorijem. Vrijednost bez predmemorije označava da se ova stranica ne sprema u predmemoriju. Za verziju HTTP/1.0 protokola na snazi ​​je "Pragma: bez predmemorije".

Zadnja promjena
Datum zadnje izmjene sadržaja. Polje je relevantno samo za statične stranice. Apache zamjenjuje ovo polje vrijednošću polja Datum za dinamički generirane stranice, uključujući stranice koje sadrže SSI.

Web stranica www.php.net nudi sljedeći kod za onemogućavanje predmemoriranja.

header("Ističe: pon, 26. srpnja 1997. 05:00:00 GMT"); // Datum u prošlosti
header("Zadnja izmjena: " . gmdate("D, d M Y H:i:s") . " GMT"); // uvijek izmijenjen
header("Kontrola predmemorije: nema predmemorije, mora se ponovno potvrditi"); // HTTP/1.1
header("Pragma: nema predmemorije"); // HTTP/1.0

Međutim, ovaj naslov je suvišan. U većini slučajeva dovoljno je:

Da biste označili dokument kao "već zastario", postavite Istječe na polje Datum.
header("Ističe: " . gmdate("D, d M Y H:i:s") . " GMT");

Pa, ne treba zaboraviti da obrasci koje zahtijeva POST također ne podliježu cachiranju.

Predmemoriranje dokumenata koji se prema zadanim postavkama ne mogu predmemorirati

Obrnuti problem može se na prvi pogled činiti apsurdnim. Međutim, i za tim postoji potreba. Osim jednostavnog minimiziranja prometa, pri izradi web programa treba voditi računa o udobnosti rada korisnika s njim. Na primjer, neke stranice vašeg poslužitelja formiraju se na temelju statičkih podataka velikog volumena. Mogućnost njihovog uključivanja u predmemoriju značajno će poboljšati brzinu poslužitelja za korisnika i djelomično osloboditi vašu od brojnih ponovljenih generacija takve stranice. Zaglavlje koje omogućuje spremanje na proxy poslužiteljima:

Povezani članak: Promocija internetske trgovine na pretraživačkoj mreži u Yandexu i Googleu: kontrolni popis za reviziju čimbenika rangiranja


Ako stranica uzima u obzir podatke pohranjene u pregledniku korisnika (vrsta i verzija preglednika, ključevi, autorizacija itd.), takva stranica se ne može spremiti na proxy, ali se može spremiti u lokalnu predmemoriju preglednika:

header("Kontrola predmemorije: privatno");

Spremanje u predmemoriju do isteka valjanosti

Gore opisana rješenja prilično su jednostavna, iako su prikladna za većinu zadataka. Ali HTTP/1.1 protokol ima alate za precizniju kontrolu predmemorije stranice, a postoje zadaci koji zahtijevaju korištenje tih mehanizama. Primjer su web aplikacije koje rade s velikim količinama podataka i predvidljivom dinamikom. Točnost podataka može se utvrditi i datumom predviđenog ažuriranja i promjenom sadržaja. Za ove slučajeve koriste se različita zaglavlja kontrole predmemorije.

Predmemoriranje prediktivnog osvježavanja

Razmotrimo primjer - cjenik koji se ažurira ponedjeljkom. Unaprijed znate da se sadržaj stranice može pohraniti u predmemoriju do novog tjedna, što bi trebalo biti naznačeno u zaglavlju odgovora kako bi se osiguralo željeno ponašanje stranice u predmemoriji.
Glavni zadatak je dobiti datum sljedećeg ponedjeljka u formatu RFC-1123

$dt_tmp=getdate(datum("U"));
header("Ističe: " . gmdate("D, d M Y H:i:s", date("U")-(86400*($dt_tmp["wday"]-8))) . " GMT");
header("Kontrola predmemorije: javno");

Ova metoda može učinkovito kontrolirati ponašanje stranice u predmemoriji i primjenjiva je na veliki broj stranica - na ovaj ili onaj način, možete odabrati vremenske intervale tijekom kojih sadržaj stranice ostaje konstantan. Realnost je da stranice većine dinamičnih web-mjesta imaju određeni vijek trajanja na temelju kojeg programer može učiniti stranicu ugodnijom za rad.

Drugi pristup, koji se koristi kod bržeg ažuriranja informacija i istovremeno velikog prometa poslužitelja (inače predmemoriranje neće biti učinkovito) je korištenje zaglavlja Cache-control: max-age=seconds, koje određuje vrijeme nakon kojeg se dokument razmatra zastario i ima veći prioritet u izračunu "svježine" dokumenta.

Vrhunski povezani članci