Clicky

Skocz do zawartości


Zdjęcie
- - - - -

[K2] Moja wersja cache dla widoków.

6 odpowiedzi w tym temacie

  • Zaloguj się, aby dodać odpowiedź

#1 panisher

panisher

    Początkujący

  • Użytkownik
  • Pip
  • 48 postów

Napisano 25 wrzesień 2009 - 23:22

Witam, Chciałbym przedstawić wam mój cache, postanowiłem go zrobić z dwóch względów: 1. miałem własną koncepcję, 2. Nie ma to jak własny kod, dopasowany pod siebie.

Pewnie nie którzy powiedzą że otwieram otwarte drzwi, to prawda :) Ale radość z własnego oprogramowania jest większa niż korzystanie w całości z frameworka.

helper/mycache.php:

Na pierwszy rzut oka wydaje się, że trochę jest przerostu treści nad formą, ale wszystko ma swoje miejsce.
$name = nazwa cache.
$rel = ścieżka prowadząca do cache w widoku np. view/layout/default/
$url = może przyjmować tablice np. tworzy nazwe z adresu URL.np. $name.'kohana/welcome/index/itd.
lub string jeżeli  mamy stałą metodĘ z różnym parametrem, jak menu dynamiczne zmienia się przez parametr to można zrobić np. $nazwa.$parametr_$parametr2.itd.
$url= array('1','Kontakt');
$time= czas po jakim odświeży się cache.


<?php defined('SYSPATH') OR die('No direct access allowed.');

class mycache_Core {

static function url($name, $rel='', $url=NULL, $time=1000) //czas w sekundach po jakich ma zaktualizować.
{
$path = '';
if(is_array($url))
{
foreach ($url as $value):
$path .= $value.'_';
endforeach;
} else
$path = str_replace("/", '_', utf8::trim($_SERVER['REQUEST_URI'], '/')).'_';

$cf2 = APPPATH.'views/';
$cacheFile = $rel.'cache/'.$path.$name;
if ( (file_exists($cf2.$cacheFile.'.php')) && ((fileatime($cf2.$cacheFile.'.php') + $time) > time()) )
$is = 1;
else
$is = 0;
return(array($is, utf8::ltrim($cacheFile, '/')));
}

static function write($name, $value)
{
file_put_contents(APPPATH.'views/'.$name.'.php',$value);
}

}


sposób użycia:
controllers/welcome.php


$cacheName zwraca tablice: array(0 lub 1, 'gotowy_url cache');
Jeżeli jest 0 to tworzy plik cache : mycache::write($cacheName[1], $menu);

Jeśli istnieje już cache i ostatni czas modyfikacji nie przekroczył $time, to wyświetla jako widok.
$menu = new View($cacheName[1]);



      public function index($url=0)
     {
          $this->template->menu= $this->menu($url);
     }

       public function menu($url=0)
{
$menu = '';
$cacheName = mycache::url('menu', 'layout/default/, array($url));

if($cacheName[0])
$menu = new View($cacheName[1]);
else
{
$menu = menu::sort_menu(menu::show($url));  
                       // helper czy model wogóle nie jest wczytywana do pamięci jeśli if jest true.
mycache::write($cacheName[1], $menu);
}
return($menu);
}


Jedyne co jeszcze trzeba utworzyć ręcznie: to folder cache w widoku, w moim przypadku jest layout/default/cache.
Dzięki temu mam cache który jest zapisywany jako html do pliku, i odczytywany przez View. Idealny sposób cachowania widoków bez użycia serialize i unserialize.

przykładowy widok cache utworzony dla menu z parametrem 2 będzie pod :  layout/default/cache/menu_2.php,
jakbyśmy tworzyli cache dla produktu id=8 który jest generowany wyłącznie z adresu kohana/product/info/2/moj-produkt.html to pozostawiamy $rel=Null i w layout/default/cache/ ->nazwa widoku będzie taka : $nazwa.kohana_product_info_2_moj-produkt.html.php dzięki temu mamy przypisany cache do adresu.

Dodatkową zaletą jest to, że jeżeli mamy opcje ustawień własnych na stronie przez użytkownika, i wybierze on z innego katalogu zestaw np. layout/user_21/ i wybrał sobie inną metodę wyświetlania menu, to jego cache menu jest przypisane do  niego.
layout/user_21/cache/menu_2.php
layout/default/cache/menu_2.php



Chciałbym poznać wasze opinie, sugestie, czy przeróbki.


#2 Maciek

Maciek

    Senior Mastah

  • Użytkownik
  • PipPipPip
  • 780 postów

Napisano 26 wrzesień 2009 - 12:57

Nie chcę burzyć radości więc napiszę aby kilka sugestii a propo kodu.

1. camelCase nie jest zalecany (cacheFile, cacheName), kwestia gustu.
2. Nie wiem czy użycie funkcji fileatime nie prowadzi do tego, że taki cache może być "nieskończony". Fragment manual'a:

Zwraca czas, kiedy nastąpił ostatni dostęp do pliku lub FALSE w przypadku błędu.

Notka: Czas dostępu do pliku przypuszczalnie zmienia się zawsze kiedy bloki danych pliku są odczytywane. To może kosztować utratę wydajności aplikacji, które regularnie korzystają z wielu plików lub katalogów.

Lepiej chyba jednak używać funkcji filemtime.
3. Nie ma (prawdopodobnie) potrzeby sprawdzania czy plik z cache'owanym widokiem istnieje. Wspomniane w punkcie 2 funkcje zwrócą FALSE w przypadku jego braku.
4. Kilka innych, mniejszych uwag.

#3 panisher

panisher

    Początkujący

  • Użytkownik
  • Pip
  • 48 postów

Napisano 26 wrzesień 2009 - 13:15

Faktycznie, sama funkcja filemtime zwróci False jeśli plik nie istnieje, ale i tak musze użyć jej dwukrotnie do warunku.
Co do funkcji filemtime i fileatime, nie zwróciłem uwagi, że istnieją dwie podobne funkcje. :)

edit:

                $saveFile = $rel.'cache/'.$path.$name; // edit do cacheFile ;
               $check = filemtime($cf2.$cacheFile.'.php');
if ($check && (($check + $time) > time()) )
$is = 1;
else
$is = 0;


#4 Maciek

Maciek

    Senior Mastah

  • Użytkownik
  • PipPipPip
  • 780 postów

Napisano 26 wrzesień 2009 - 13:27

Faktycznie, sama funkcja filemtime zwróci False jeśli plik nie istnieje, ale i tak musze użyć jej dwukrotnie do warunku.

A sprawdziłeś że musisz ? ;)

U mnie poniższy kod działa zgodnie z założeniem.
if(FALSE + time() > time())
return FALSE;
else
return TRUE;


#5 panisher

panisher

    Początkujący

  • Użytkownik
  • Pip
  • 48 postów

Napisano 26 wrzesień 2009 - 18:19

a no nie spradziłem :), no tak 0+time>time.


edit...

Nie przechodzi walidyzacji php

echo filemtime('dsadas.php');
Warning: fileatime() [function.fileatime]: stat failed for dasd.php
Sama funkcja nie zwraca Bolean True or False, a błąd lub wynik. Choć dziwne, ciekawe czy to błąd php nie zwrócili na to uwagi czy to zamierzony cel, z jakiś względów bezpieczeństwa.

Czyli powracamy do oryginalnej wersji.


#6 Maciek

Maciek

    Senior Mastah

  • Użytkownik
  • PipPipPip
  • 780 postów

Napisano 26 wrzesień 2009 - 20:24

Tak, mój błąd. Rzadko używam funkcji związanych z plikami i pewnie dlatego. Funkcja filemtime (fileatime oczywiście też) zwraca warning w przypadku gdy sprawdzany plik nie istnieje.

#7 panisher

panisher

    Początkujący

  • Użytkownik
  • Pip
  • 48 postów

Napisano 26 wrzesień 2009 - 20:45

Czy ja wiem czy to twój błąd ;] Powiedzła bym, że to bugs php :)
Przecież funkcja powinna zwracać bolean przynajmniej w instrukcji.

-------- Fajnie całość zamknełem do mycache, w tej chwili aby uruchomic cache wystarczy jedna linijka.
np. dla subskrypcji która jest na każdej stronie w template _subskryption która jest ładowana do $this->tamplate->subskryption=$this->_subskryption;

został zacchowany formularz generowany przez kohane i zapisany w modelu.

$submail = mycache::start('submail', array('Myform_Model', 'submail'));
Tworzy cache widok submail, z modelu myform, uzywajac metody submail. :)

Załadowane w 0.0502, przy użyciu 1.04MB pamięci

Standardowo zabieram, 0.09~. i 1.89mb. z menu drzewko na id_parets, i subskrypcji.





Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych