Kom ihåg mig?
Home Menu

Menu


Cache-filer med PHP

Ämnesverktyg Visningsalternativ
Oläst 2010-12-09, 21:01 #1
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
Standard Cache-filer med PHP

Hej,
Jag håller på med ett cache-system till ett projekt. Min applikation läser in "originalfilen" och skapar utifrån denna en php-fil som skriver ut innehållet.

Exempel:

Min original-fil:
HTML-kod:
<div class="content">
  <p>Namn: {name}</p>
</div>
Genererad php-kod:
PHP-kod:
<?php defined('IN_APP') or die('Access denied'); ?>
<div class="content">
  <p>Namn: <?php echo $name?></p>
</div>
Dessa cachefiler läses in direkt i min "huvud-template" med include() för att skriptet skall vara så resurssnålt som möjligt.
Jag använder inte output-buffering.

Vad jag nu vill ha är möjlighet att i min cache-fil lägga in en variabel (t.ex. $title) som skall vara tillgänglig "tidigare" i skriptet (när sidhuvudet skrivs ut).

Jag har kommit fram till några alternativ:

1.
Omsluta min HTML-kod med en php-funktion, output().
Läsa in cachefilen innan sidhuvudet skrives ut och således komma åt $title-variabeln.
När innehållet skall skrivas ut anropas ovanstående funktion, output().

2.
Ha två separata cache-filer: En för titelvariabeln och en för innehållet och läsa in dessa separat där de behövs.

3.
Ha en cache-fil som agerar både title och content beroende på var den anropas:
PHP-kod:
<?php defined('IN_APP') or die('Access denied'); 
if (isset(
$getTitle) && $getTitle)
    return 
'Sidrubriken';
?>
<div class="content">
  <p>Namn: <?php echo $name?></p>
</div>
När jag skall hämta titeln sätter jag först $getTitle = true och inkluderar filen. När jag sedan skall ha innehållet sätter jag $getTitle = false och inkluderar filen igen.

---

Vilket av ovanstående (eller kanske en annan lösning) rekommenderar ni?

Andra synpunkter?
qson är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-09, 22:07 #2
coredevs avatar
coredev coredev är inte uppkopplad
Bara ett inlägg till!
 
Reg.datum: Sep 2007
Inlägg: 1 554
coredev coredev är inte uppkopplad
Bara ett inlägg till!
coredevs avatar
 
Reg.datum: Sep 2007
Inlägg: 1 554
Jag skulle nog kanske pröva med att cacha datat istället för hela sidor, om det är möjligt i ditt scenario. Datat cachar du fint med t.ex. memcached eller i PHP-arrayer i filer som du includar i dina script. Grejjen är att med en sjysst PHP-accelerator (typ APC) så genereras själva scriptet så otorligt snabbt utan att man behöver cacha hela sidor.

Går gärna in mer på detaljer om du tror att detta är ett spår för dig.
coredev är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-09, 22:17 #3
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
Tyvärr tror jag inte det är något för mig.
Originalfilerna är rena html-filer (fullständiga webbsidor) som jag läser in i php, modifierar dem och lagrar som "cache"-filer. Kan därför inte lagra bara data det känns som dubbelt arbete att först parse-a (tolka) indata, lagra datan i cache, och sedan rendera html-kod igen (nästan som ursprunget).
Jag har ingen dynamisk data i skripten förutom $title.

Skriptet kollar om det finns en cache-fil för den begärda sidan, om det inte finns så läses originalfilen in och en cache-fil skapas. Annars kör den cachefilen och sedan inget mer.
qson är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-10, 00:31 #4
KarlRoos KarlRoos är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Jul 2007
Inlägg: 1 416
KarlRoos KarlRoos är inte uppkopplad
Har WN som tidsfördriv
 
Reg.datum: Jul 2007
Inlägg: 1 416
Precis som coredev säger så är det smartast. För att förklara med kod:
PHP-kod:
// Detta skall du cacha
$file 'hej.php';
$vars = array(
     
'hej' => 'WN är mysigt'
);

// Det nedan skall du ej cacha
$content file_get_contents($file);

foreach(
$vars as $key => $val){
     
$search[] = '{' $key '}';
     
$replace[] = $val;
}

echo 
str_replace($search$replace$content); 
KarlRoos är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-10, 09:46 #5
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
Vill förtydliga lite till.

Jag har ett antal HTML-filer (fullständiga HTML-dokument) som originalfiler. Jag läser in dessa HTML-dokument och plockar ut den del av dokumentet jag behöver (en div-tagg mitt på sidan) skapar en cache-fil av detta (egentligen en ny html-fil med bara min div-tagg).

När jag läser cache-filen läser den in html-koden (min div-tagg) rakt upp och ner. Inga ersättningar behöver göras (jag har ingen dynamisk data som skall behandlas).

Vad jag vill få till är att även få med <title>-taggen från mitt originaldokument, men lagra det separat så jag kan hämta titeln för sig och inenhållet för sig från cachefilen.

Om jag skall följa era instruktioner skall jag alltså läsa in originaldokumentet, göra om det till en php-array, spara som php-kod i en cache-fil och när jag skall läsa in cachen så skall den då generera ny html-kod (som det nästan identisk ut med originaldokumentet)? Känns som att man tappar fördelen med cache då. Då kan jag ju lika gärna läsa in originaldokumentet direkt och bara plocka ut med DOM varje sidvisning.
qson är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-10, 12:19 #6
emilvs avatar
emilv emilv är inte uppkopplad
Bara ett inlägg till!
 
Reg.datum: Feb 2004
Inlägg: 1 564
emilv emilv är inte uppkopplad
Bara ett inlägg till!
emilvs avatar
 
Reg.datum: Feb 2004
Inlägg: 1 564
Något i stil med detta (som väl liknar ditt alternativ 3) skulle jag nog gjort:

PHP-kod:
<?php
//Save
$object = array('text' => 'HTML content''title' => $title);
file_put_contents('cachefile'serialize($object));
?>
PHP-kod:
<?php
//Load
$object unserialize(file_get_contents('cachefile'));
?>
Detta kräver dock lite RAM och du verkar ju vilja trycka ut datat direkt utan mellanlagring av hela filen i minnet (notera att din kod INTE uppfyller det kravet för närvarande). En högpresterande lösning vore då ditt alternativ 2, gärna kombinerat med en minnescache (memcached eller spara filerna på en RAM-disk). Men slopa include för då måste cachefilerna köras genom PHP-tolken trots att de bara innehåller ren HTML-kod. Använd readfile istället.

En optimering som gör att du slipper öppna två filer (varje filöppning tar såklart prestanda och i värsta fall disksökning till skilda delar av hårddisken) kan vara att utveckla ett eget filformat för alternativ 3. Lägg till exempel titlen på första raden och resten av filen sedan. Exempel:

PHP-kod:
<?php
//Save
$save $title ."\n"$content;
file_put_contents('cachefile'$save);
?>
PHP-kod:
<?php
//Load
$fp fopen('cachefile''r');
/*
Where you need the title, output first line.
Do not close the file pointer!
*/
echo fgets($fp);

/*
Where you later want the content, just fpassthru the rest of the file.
This will pass the content directly to the output buffer (and with output buffering disabled, directly to the network).
*/
fpassthru($fp);
?>
emilv är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-12, 12:13 #7
NeoTech NeoTech är inte uppkopplad
Medlem
 
Reg.datum: Sep 2006
Inlägg: 90
NeoTech NeoTech är inte uppkopplad
Medlem
 
Reg.datum: Sep 2006
Inlägg: 90
Första man ska fråga sig, varför cachar man?
Är det för o bespara I/O tid i databasen? Eller är det för o slippa repetera onödiga loopar?
En sak e väl säker, man cachar statiskt innehåll inte dynamiskt.

Om man e ute efter o bespara I/O tid i Db'n så e väl steg 1, att skriva smartare SQL kod, steg2 är o titta på det statiska datat, vad kan dumpas till filer. Disk I/O e som regel snabbare än SQL I/O vid stora överföringar. - kör man mysql ska man komma ihåg att MySQL belastar servern i dubbel benämning då de inte är en riktig Databas i stil med DB2 standardiseringen som har sina egna filsystem.

Ett sätt o komma runt onödiga CPU belastningar av loopar t.ex är att bryta ner template motorn att hantera ett .NET liknande tänk vad gäller controllers / helpers och kod separerade view filer. Ett bra modulärt ramverk kan ta bort mycket av dom onödiga turerna i en while/foreach loop. För vi ska minnas i webspråk så är det looparna som är CPU tids dödarna.

Om man spolar tillbaka dock lite, att lägga sin affärslogik i databaslagret är ofta en smart lösning, att jobba med procedures, triggers och functions i T-SQL - besparar ofta webbservern mkt processenade, då Databasen alltid är absolut bäst på att hantera stora mängder string data. Samt komplexa mattematiska beräkningar. Att låta databasen serva logik lagret (php) med färdig stringdata kan även det skapa stora vinster i prestanda vad gäller att serva upp statisk information.

Behöver man bara cacha för att sidorna inte uppdateras ofta, då är det bästa troligen o dumpa till html filer och låta filsystemet göra det de är bäst på - serva filer.

Att cacha kan göra mycket fördelar för hårt trafikerade siter, men man ska komma ihåg det finns många sätt o cacha på, dom ger olika fördelar på, och det finns inget som säger att man inte får kombinera flera olika typer av cache funktioner.

Personligen favoriserar jag affärslogik i SQL lagret, med ett MVC ramverk som har total kod/design separering, och när det inte räcker till så stoppar man på en Varnish Caching http proxy server som verkligen kan snabba upp saker o ting. Halvera access tider många ggr.

Vet att detta va inget direkt svar på din initiala fråga, men att bygga ett bra väl fungerande cache system kräver oftast lite mer planering och baktanke, jag tror du nog har bra koll på koden egentligen då du öht överväger att koda en cache hantering. Så då kanske det är procedurerna kring cache hantering och optimeringen av dessa som kan vara bättre o tänka över. =)
NeoTech är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-12, 12:36 #8
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
Oj NeoTech, det var ett informationsrikt inlägg, och mycket intressant!
Som du skriver är det inte riktigt vad jag behöver (mitt skript består av två filer, totalt 160 rader enkel php-kod)
Det är statiskt innehåll jag vill cacha .Det finns inget dynamiskt innehåll på sidan, men jag kan inte heller serva rena html-filer då det det skall vara transparent mot redaktören som lägger in html-filer i en mapp som sedan skall parsas och cachas. Man ska inte behöva gå in och "manuellt" uppdatera cache. Därför använder jag php och filemtime för att upptäcka när en originalfil ändrats eller lagts till.

Anledningen att jag vill cacha är för att undvika en dom-parser vid varje sidläsning. Jag läser in ett html-dokument till DOMDocument, plockar ut några få element ur detta, ändrar några attribut för vissa element och skickar detta till webbläsaren. Det känns onödigt att parsa samma html-dokument vid varje sidladdning när jag kan parsa den en gång, spara resultatet och sedan bara parsa igen om originalfilen ändrats.

EDIT: Skall komma ihåg ditt inlägg till mina övriga projekt :-)
qson är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-12-14, 10:15 #9
NeoTech NeoTech är inte uppkopplad
Medlem
 
Reg.datum: Sep 2006
Inlägg: 90
NeoTech NeoTech är inte uppkopplad
Medlem
 
Reg.datum: Sep 2006
Inlägg: 90
Man behöver jue eg. inte "manuellt" gå in o uppdatera cachen heller, utan varje gång det sker en html fil uppdatering i en mapp så passerar ett cronjob den mappen säg varje minut, och adderar en flagga till en korsreferens tabell bara, och varje gång en sida laddas så går ett php script igenom referens tabellen och ser vilken fil och när den uppdateras gör en jämförelse mot den som är servad på webbplatsen och sedan mergar / ersätter den med den filen som redan finns utlagd..

Det går jue o bygga rätt mkt automatiska tjänster runt schemaläggning på scriptbasis som kan göra en hel del av det där jobbet åt dig så du slipper koda tokigt tunga presentations script, så den lilla vinsten du gjorde i en ände äts upp i den andra änden av ett tungt script som skall presentera data.. =)
NeoTech är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 21:35.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017