Polski support
KohanaPHP Framework
FORUM Polskiego Supportu KOHANA Framework
9 Wrzesień 2010, 02:13 *
Witamy, Gość. Zaloguj się lub zarejestruj.

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: 18.10.2009 - wydanie 3.0.1
Strony: [1]   Do dołu
  Drukuj  
Autor Wątek: Moja wersja cache dla widoków.  (Przeczytany 1097 razy)
panisher
Nowy użytkownik
*
Offline Offline

Wiadomości: 30


Zobacz profil
« : 26 Wrzesień 2009, 00: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 Uśmiech 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(
$isutf8::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.
« Ostatnia zmiana: 26 Wrzesień 2009, 00:51 wysłane przez panisher » Zapisane
Maciek
Zaawansowany użytkownik
****
Offline Offline

Wiadomości: 427



Zobacz profil
« Odpowiedz #1 : 26 Wrzesień 2009, 13: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.
Zapisane
panisher
Nowy użytkownik
*
Offline Offline

Wiadomości: 30


Zobacz profil
« Odpowiedz #2 : 26 Wrzesień 2009, 14: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. Uśmiech

edit:
                $saveFile $rel.'cache/'.$path.$name// edit do cacheFile ;
                
$check filemtime($cf2.$cacheFile.'.php');
	
	
if (
$check && (($check $time) > time()) )
	
	
	
$is 1;
	
	
else
	
	
	
$is 0;
« Ostatnia zmiana: 26 Wrzesień 2009, 14:21 wysłane przez panisher » Zapisane
Maciek
Zaawansowany użytkownik
****
Offline Offline

Wiadomości: 427



Zobacz profil
« Odpowiedz #3 : 26 Wrzesień 2009, 14: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 ? Mrugnięcie

U mnie poniższy kod działa zgodnie z założeniem.
if(FALSE time() > time())
	
return 
FALSE;
else
	
return 
TRUE;
Zapisane
panisher
Nowy użytkownik
*
Offline Offline

Wiadomości: 30


Zobacz profil
« Odpowiedz #4 : 26 Wrzesień 2009, 19:19 »

a no nie spradziłem Uśmiech, 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.
« Ostatnia zmiana: 26 Wrzesień 2009, 21:15 wysłane przez panisher » Zapisane
Maciek
Zaawansowany użytkownik
****
Offline Offline

Wiadomości: 427



Zobacz profil
« Odpowiedz #5 : 26 Wrzesień 2009, 21: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.
Zapisane
panisher
Nowy użytkownik
*
Offline Offline

Wiadomości: 30


Zobacz profil
« Odpowiedz #6 : 26 Wrzesień 2009, 21:45 »

Czy ja wiem czy to twój błąd ;] Powiedzła bym, że to bugs php Uśmiech
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. Uśmiech

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.
« Ostatnia zmiana: 27 Wrzesień 2009, 03:50 wysłane przez panisher » Zapisane
Strony: [1]   Do góry
  Drukuj  
 
Skocz do: