Yksinkertainen, viimeksi ladattujen sivujen näyttämiseen tarkoitettu pätkä. Tästä on sitten erittäin helppo muokata vaikkapa viimeksi ladatut tiedostot -koodi.
Koodi vaatii riittävät oikeudet sijaitsemalleen kansiolle tai tiedoston lataukset.dat, chmodattuna ~0666 sekä lisäksi kaikkien listattavien sivujen alkuun 1. pätkän.
DEMO: http://atteweb.net/?p=viimeksi_ladattu
E1: kaksi versiota
<?php /* Jokaisen listattavan sivun alkuun */ $tiedosto = "lataukset.dat"; // annetaan tiedosto $maksimi = 25; // suurin määrä latauksia tiedostossa function lataus_tiedostoon(){ global $tiedosto; global $maksimi; if(!file_exists($tiedosto)){ // jos tiedostoa ei löydy, yritetään luoda sellainen if(!@touch($tiedosto)){ // jos ei voida luoda tiedostoa, näytetään virheilmoitus die("<h2>Permission denied!</h2><p>Tiedostoa ei voitu luoda automaattisesti => luo tiedosto manuaalisesti!</p>"); } if(!@chmod($tiedosto, 0666)){ // jos tiedostolle ei voida antaa riittävästi oikeuksia, näytetään virheilmoitus die("<h2>Permission denied!</h2><p>Tiedostolle ei voitu antaa oikeuksia automaattisesti => chmodaa tiedosto ~0666!</p>"); } } $file = file($tiedosto); // luetaan tiedosto taulukkoon ja muodostetaan rivi valmiiksi $rivi = time()."|:|".$_SERVER['REMOTE_ADDR']."|:|http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']."|:|"; $rivi = str_replace(array("\n", "\r"), "", $rivi); // rivinvaihdot pois (?) $rivi = htmlspecialchars($rivi); // html pois $rivi = $rivi."\r\n"; ignore_user_abort(true); if(count($file) <= $maksimi){ // jos tiedostossa on vähemmän rivejä, kuin sallittu $tt = @fopen($tiedosto, "a"); // kirjoitetaan perään if (flock($tt, LOCK_EX)) { @fwrite($tt, $rivi); @flock($tt, LOCK_UN); } @fclose($tt); }else{ // muutoin poistetaan 1. rivi $tt = @fopen($tiedosto, "w"); if (flock($tt, LOCK_EX)) { for($i=1; $i<$maksimi; $i++){ @fwrite($tt, $file[$i]); } @flock($tt, LOCK_UN); } @fwrite($tt, $rivi); @fclose($tt); } ignore_user_abort(false); } lataus_tiedostoon(); // kutsutaan funktiota ?>
<?php /* Tulostaa viimeksi ladatut sivut taulukkoon (xxx.php versio) */ $file = file("lataukset.dat"); // ladataan tiedosto taulukkoon $file = array_reverse($file); // ja käännetään se $juuri = substr($tiedoston_URL, 0, strrpos($tiedoston_URL, '/')).'/'; echo'<table> '; for($i=0; $i<count($file); $i++){ // silmukoidaan kaikki rivit $tiedot = explode("|:|", $file[$i]); // erotellaan tiedot $nimi = substr($tiedot[2], 0, strrpos($tiedot[2], '/')).'/'; // määritetään juuri $nimi = str_replace($nimi, "", $tiedot[2]); // poistetaan juuri $nimi = str_replace(".php", "", $nimi); // poistetaan nimestä .php pääte $nimi = ucfirst(strtolower($nimi)); // nimen 1. kirjain isolla, muut pienellä if($tiedot[1] == $_SERVER['REMOTE_ADDR']){ // jos ip on oma, näytetään red tausta echo'<tr style="background: red;"><td>'.date("H:i", $tiedot[0]).'</td><td><a href="'.$tiedot[2].'">'.$nimi.'</a></td></tr> '; }else{ // muutoin ei erikoisia muotoiluja echo'<tr><td>'.date("H:i", $tiedot[0]).'</td><td><a href="'.$tiedot[2].'">'.$nimi.'</a></td></tr> '; } } echo'</table>'; ?>
<?php /* Tulostaa viimeksi ladatut sivut taulukkoon (?sivu=xxx versio) */ // muista muokata riviä 20! $file = file("lataukset.dat"); $file = array_reverse($file); echo'<table>'; for($i=0; $i<count($file); $i++){ $tiedot = explode(":|", $file[$i]); $nimi = $tiedot[2]; if($tiedot[1] == $_SERVER['REMOTE_ADDR']){ echo'<tr style="background: red;"><td>'.date("d.m.y H:i", $tiedot[0]).'</td><td><a href="?sivu='.str_replace(" ", "_", strtolower($tiedot[2])).'">'.$nimi.'</a></td></tr>'; }else{ echo'<tr><td>'.date("d.m.y H:i", $tiedot[0]).'</td><td><a href="?sivu='.str_replace(" ", "_", strtolower($tiedot[2])).'">'.$nimi.'</a></td></tr>'; } } echo'</table>'; ?>
Tuosta listaajasta kannattaisi tehdä luokka, ja listausmetodista staattinen, jolloin jokaisen sivun alussa tarvitsisi kutsua vain:
Lisäksi luokalle voisi antaa attribuutteja, esim. kuinka jokainen entry tallennetaan ja mihin, ja esitetäänkö viimeksi ladattu sivu vain kerran peräkkäin, yms.yms. YAML-tiedostot ovat pop asetusten tallentamiseen :).
Kyllähän tähä saa vaikka mitä ympättyä, mutta tämä nyt on vain yksinkertainen esimerkki, miten se tehdään.
Ilman ymppäyksiä luokka olis selkeempi kun ei tartteis tuota pitkää rimpsua kopsata joka tiedostoon. Tuosta edellisestä viestistäni puuttuu vielä toki require (jonka siihen lisäänkin nyt), ellei autoloaderi hoida sitä. Voihan toki pelkän funktionkin laittaa eri tiedostoon ja tuoda aina sen, mutta sama se on tässä vaiheessa tehdä luokka, jota on myöhemmin helppo lähteä laajentamaan.
Miten require liittyy tähän?
Tarvitsisikohan tuohon tiedoston lukitsemisen, ettei kaksi samanaikaista sivupyyntöä voisi edes teoriassa sotkea tiedostoa kirjoittamalla siihen samanaikaisesti?
uups... Piti se siihen lisätä, mutta en sitten muistanut => lisätään
ei toi flock() toimi, uskokaa jo.
miksi ei? mikä toimii?
Kyllähän ne kai toimii mutta logiikka miten niitä käytät ei mielestäni oikein toimi. Esim:
$tt = @fopen($tiedosto, "w");
if (flock($tt, LOCK_EX)) {
Tiedosto jää tyhjäksi fopenin jäljiltä jos lukitus ei onnistu.
Ja:
$file = file($tiedosto);
Mitäs tässä tapahtuu jos tiedosto on lukittu? Ja kirjoitat datan kuitenkin takas sinne tiedostoon.
Aihe on jo aika vanha, joten et voi enää vastata siihen.