http://nospor.pl/cache.html
http://nospor.pl/download/idfolder/18/
Prezentuje moją nową klasę Cache. Jak nazwa wskazuje klasa służy do zarządania cachem. Do cache'u można wkładac stringi, tablice, liczby, obiekty. Dany obiekt cache'u należy zawsze do jakiejś grupy lub do kilku grup. Gdy nie podamy grupy, obiekt trafi do grupy domyślnej.
Obiekty w cache'u mają swoją żywotność, którą można regulować według własnych potrzeb. Obiekty moga byc wazne przez sekundy, minuty, godziny, dni itp...
Dodatkowo można uzależnic obiekt od pliku zewnetrznego bądź też od kilku plikow. Cache straci wowczas swoją waznosc, gdy w danym pliku zewnetrznym pojawią sie jakies zmiany. Uzależnienie obiektu od kilku plikow moze byc przydatne, gdy np. tworzymy obiekt na podstawie kilku plikow xml.
Nazwy obiektów mogą byc rownież hashowane. Ma to powiedzmy zastosowanie przy cacheowaniu zapytan. Zamiast nazwy "select * from tabela order by alamakota", pojawi nam sie ladny hash
Czyszczenie cache odbywa sie na 4 sposoby:
1) wyczyszczenie calego cache'u
2) skasowanie wybranego(ych) obiektu(ow)
3) wyczyszczenie wybranej (ych) grupy
4) obiekt traci swoją ważność
Zapraszam do używania, testowania i zgłaszania ewentualnych uwag/błędów.
edit:
począwszy od wersji 1.2 Cache dziala na zasadzie sterownikow I/O. Wraz z paczką dołączony jest sterownik działający na plikach oraz sterownik operujacy na pamieci, przez co obsluga Cache jest jeszcze szybsza.
Dodana zostala suma kotrolna, mająca swoje zastosowanie szczegolnie przy operacjach na pamieci.
edit (2006-09-08):
No i jest Cache ver. 2.0
Czemu taki przeskok w numeracji? Ano odszedlem "troche" od sposobu konfiguracji cache.
Wczesniej, aby moc dzialac na plikach i na pamieci trzeba bylo definiowac dwa obiekty Cache. Teraz mozliwe jest zdefiniowanie kilku sterownikow dla jednego obiektu Cache.
Wprowadzilem przymus definiowania grup (domyslnie definiowana jest jedna grupa jesli komus przymus nie odpowiada ). Dzieki takiemu zastosowaniu mozna parametryzowac grupy, a co za tym idzie obiekty do nich przypisane. Mozna dla grupy okreslic jakie sterownik ma ja obslugiwac, jej czas zycia, sprawdzanie sumy, hashowanie i inne. Jesli w jakiejs chwili nam sie odmienia, ze configi zamiast na dysku maja byc zapisywane w pamieci, wystarczy wowczas tylko zmienic sterownik dla grupy, bez latania po wszystkich obiektach i zmieniania. Oczywiscie mozna zdefiniowac czas zycia obiektu w cache tylko dla niego, nadpisujac w ten sposob parametry grupy.
Teraz by pobrac obiekt z cache trzeba okreslic do jakiej grupy nalezy. Wczesniej tego nie trzeba bylo robic. No ale jest to niezbedne by zaladowac chociazby odpowiedni sterownik do obslugi obiektu.
Oczywiscie jak sie nie poda tego parametru, zaczytana zostanie grupa domyslna.
Gratulacje!
Ładny skrypt, podoba mi się cache plików zewnętrznych
Na prawdę dobra robota, przyda się
Dobra robota.
witam ...
szkoda że tylko pliki a nie np. apc :/ szukam czegoś co łączyło by zmienne aplikacji (przechowywane w apc) ze zmiennymi sesji (standardowo SESSION) poprzez spójny interfejs ... ale nic ciekawego nie widzę więc chyba skończy się na tym że napisze sam ...
ale pomysł i wykonanie bardzo dobre
pozdrawiam
@nospor - pozwolilem sobie uruchomic ten przyklad prezentujacy mozliwosci Twojej klasy. Moje uwagi na goraco.
Zrezygnuj z ostrzeżen na rzecz wyjatkow. Jesli cos jest pierdolka to zwracaj true albo false, ale nie NOTICE lub WARNING. Jesli uzaleznie istnienie jakiegos elementu w cachu od pliku, a potem zapomne o tym i ten plik usune to zuytkownik zobaczy komunikaty, ktorych nie powinien widziec. Jesli bylyby to wyjatki to zawsze moglbym je jakos obsluzyc. Poza tym kiedy walniesz NOTICE to skrypt sie nie zatrzymuje i potem widze kolejne ostrzezenia tyle, ze tym razem generowane juz przez parser php.
Drugie pytanie. Czy probowales juz cachowac tym faktycznie jakis obiekt, a pobierac go potem z cachu? Przed pobraniem nie tworz zadnego innego obiektu danej klasy.
Odpalilem raz skrypt potem odswierzylem widok i zobaczylem NOTICE, ze nie ma pliku xml, a potem, ze jaks tam zmienna nie jest tablica. Nie napisze Ci dokladnie co to bylo bo nie mam w tej chwili dostepu do swojego kompa.
Co do rzucania wyjatkow z byle powodu. To faktycznie nie jest dobry pomysl. Ale pewne rzeczy mozesz obsluzyc w sposob domyslny. Jezeli chcesz usunac grupe ktorej nie ma to zwyczajnie powinienes zignorowac zadanie i dac true bo w koncu chodzi o to aby tej grupy nie bylo. I analogicznie w wielu innych przypadkach. Poza tym sa jeszcze true i false.
Masz jeszcze inne wyjscie. Flage debug. Jak true podajesz ostrzezenia jak false nic nie wyswietlasz.
Uzycie slowa obiekt mnie troszke zmylilo. Myslalem, ze serializujesz obiekty i w ten sposob je cachujesz, a przy odczycie deserializacja.
<?php class A { private $property; public function __construct($property) { $this->property = $property; } public function getProperty(){ return $this->property; } } http://www.php.net/session_start(); if($_GET['action'] != 'read') { $_SESSION['foo'] = 'Hello World!'; $_SESSION['counter']++; $_SESSION['A'] = http://www.php.net/serialize(new A('Eureka!')); } http://www.php.net/echo $_SESSION['foo'] . "<br />"; http://www.php.net/echo $_SESSION['counter'] . "<br />"; $A = http://www.php.net/unserialize($_SESSION['A']); if($A instanceOf A) { http://www.php.net/echo 'Property: ' . $A->getProperty() . "<br />"; } ?>
hihi, http://pl.php.net/manual/pl/function.serialize.php
stary a glupi jak but... nigdy nie serializowalem obiektow to nawet do glowy mi nie przyszlo ze mozna:
Moglbys do tego dopisac hendlery sesji i mialbys wlasne sesje z dodatkowymi rozbudowanymi mozliwosciami dotyczacymi kontroli trwalosci zmiennych. Oczywiscie uzycie Twojego - nazwijmy to cachera w roli sesji byloby opcja, a nie domyslnym przeznaczeniem.
Domyslnie zmienne zachowywaly by sie tak jak to zwykle bywa w przypadku sesji, ale udostepnil bys specjalne metody umozliwiajace ustawienie czasu trwalosci indywidualnie dla kazdej zmiennej, lub metody umozliwiajace uzaleznienie istnienia poszczegolnych zmiennych np. od istnienia danego pliku.
No dobra, no to jest kolejna wersja.
Poprawki:
- ustawienie poziomu raportowania bledow (wlasciwosc $errorLevel)
- mozliwosc wkladania obiektów typu object (wiem, smiesznie to brzmi). Przy wkladaniu obiektow, klasa wkladanego obiektu moze zawierac magiczne metody __sleep() oraz __wakeup(), ktore wykonuje dane rzeczy przed wlozeniem obiektu do cache i po pobraniu go. Należy pamietac by metoda __sleep() zwracala tablicę zmiennych, ktore mogą byc serializowane.
@bigZbig z tymi sesjami to dobrze mowisz moze w przyszlosci...
Klasa wygląda bardzo fajnie i tak samo działa, ale zastanawia mnie jedna rzecz. Dlaczego czas żywotności obiektu w cache'u ustawiany jest jako parametr metody Get, a nie Put? Wydaje mi się, że żywotność powinna być określania w momencie wkładania do cache'u... podobnie jak z plikami cookies.
@Foxer a Ty wiesz, ze jak ja pierwszy raz widzialem podobna klase w javie to tez mnie to dziwilo. Jednak gdy zacząlem jej uzywac na powaznie zauwazylem w tym sens.
1) przy put informacje o zywotnosci musialbym trzymac w pliku razem z obiektem
2) przy put nie bylbym w stanie zmienic zywotnosci obiektu w cache. wlozylem na tydzien i nijak tego zmienic, chyba zeby pisac dodatkowe metody lub czyscic caly cache. przy get ja to sobie moge w kazdej chwili regulowac
3) przypadek teoretyczny: wkladasz obiekt do cache. korzystac z niego bedą dwie akcje. jedna akcja zadowala sie odswierzeniem miesięcznym, druga akcja potrzebuje juz tygodniowego odswierzenia. przy put tego nie osiagniesz, chyba ze wrzucisz dwa obiekty dla kazdej akcji. wiem , ze taka sytuacja raczej nie ma praktycznego miejsca, ale teoretycznie jest
pozatym wad przy get nie widze. jesli ty widzisz to prosze podaj, moze da sie cos usprawnic.
Wad również nie widzę, same zalety . Poprostu patrząc "estetycznie" zdziwiłem się dlaczego okres ważności jest ustawiany przy Get. Oczywiście "na upartego" : P możnaby ustawiać ważność obiektu przy Put, zapisując tą informację w pliku razem z obiektem, dodać metodę która mogłaby edytować tą wartość, itd... ALE... byłoby to pozbawione sensu skoro Twój sposób jest prostrzy i szybszy Przekonałeś mnie.
No i jest ver. 1.2
Na sluszną uwagę nasty_psycho, wprowadzilem sterowniki operacji wejscia/wyjscia. Teraz kazdy moze sam
zdecydowac gdzie i w jaki sposob chce cacheowac dane bez ingerencji w kod klasy.
Na chwilę obecną istnieje moj domyslny sterownik operujacy na plikach. Niedlugo byc moze pojawi sie inny sterownik zapisujący dane w pamięci operacyjnej. Jak zapewne sie orientujecie przyspieszy to znacznie dzialanie cache.
Samo korzystanie z cache nie uleglo zmianie. W konstrukorze nalezy podac obiekt sterownika. Mozna jak dotej pory podac sciezke do katalogu cache, wowczas zostanie zaladowany domyslny sterownik.
Kolejną nowością jest suma kontrolna. Umozliwia ona zwalidowanie, czy obiekt zawarty w cache nie zostal ręcznie zmodyfikowany, przez co zawiera wadliwe dane.
edit:
Zgodnie z zapowiedzią pojawia się sterownik operujący na pamięci operacyjnej, przez co działanie cache jest jeszcze szybsze. Sterownik napisał nasty_psycho a ja go lekko poprawilem.
Oto przykladowy porownanie szybkosci dzialania na plikach i na pamieci:
Klasa fajna, nawet bardzo. Zastanawia mnie tylko dostepnosc u uslugodawcow modulu "shmop". chyba nie jest zbyt popularny. I przy okazji dodatkowe pytanie jakby w tym miejscu (mam namysli jako sterownik) spisywala sie tabela w bazie danych typu MEMORY (SQLite albo MySQL)?
A czy dodanie tych kilku "&" nie powoduje zwracania warningow kiedy skrypt uruchamiany jest na php5 bez trybu kompatybilnosci?
Osobiscie uwazam, ze uruchamianie php5 w wersji kompatybilnosci z php4 wprowadza jedynie wiecej zamieszania i moze powodowac bledy w dzialaniu skryptow. Dlatego lepszym rozwiazaniem jest uruchomienie na serwerze obu wersji php tj 4 i 5. Z tego tez wzgledu uwazam, ze jezeli juz chcesz zapewnic aby Twoj projekt dzialal rowniez na php5 z wlaczona kompatybilnoscia to napisz poprostu swoja klase w wersji dla php4.
super klasa, tylko przydałaby się jeszcze jedna funkcjonalność. Chodzi o ustawianie katalogów, w jaki mają być wgrywane pliki cache. W tej chwili mozna ustawić jeden katalog w konstruktorze klasy, a według mnie przydałoby się, aby można było ustawiać katalogi np. dla grup, czy nawet pojedynczych plików cache.
Dzięki temu raz, że można by sobie ładnie posegregować pliki, a dwa aplikacja taka byłaby wydajniejsza, gdy będziemy mieli tysiące plików cache.
Wiesz czego mi tu tylko brakuje ? Inerfejsu dla sterowników. Poza tym miodzio.
Mam taką sytuację, mam na stronie możliwość komentowania.
Cechuje pobieranie z bazy daty, autora, treść komentarza.
A czy jest możliwość aby zrobić żeby pobierało nowe komentarze ale dopiero wtedy kiedy coś dodał nowy??
A nie po upływie pewnego czasu.
ok jakoś poszło ale jak chciałem to wykorzystać tutaj http://www.badongo.com/file/3029025
Plik mieści się na forum ale nie chciałem zaśmiecać, plik php tylko dodane rozszerzenie .txt
To pokazuje mi
<?php Fatal error: Cannot redeclare class cacheexception in /home/test/ftp/cms/components/com_datsogallery/cache/Cache.class.php on line 661 ?>
<?php catch (CacheException $e){ http://www.php.net/echo '<span style="color:red">'.$e->getMessage().'</span>'; } ?>
<?php Parse error: syntax error, unexpected T_IF, expecting T_CATCH in /home/test/ftp/cms/components/com_sef/sef.php on line 204 ?>
Problem był z ścieżkami;/
dzięki
Chciałbym tutaj napomnieć o cachowaniu danych w plikach.
Sam osobiście korzystam właściwie tylko z tej metody i ważne jest żeby nie przesadzić z ilością plików w katalogu (ponieważ wtedy cały pomysł Cache na plikach może nie spełniać swojego zadania)
Załóżmy np limit 1000. Przy zapisywaniu pliku szukamy w jego nazwie liczby dzięki której będzie można pogrupować pliki w katalogi.
Wyciągniętą liczbę dzielimy przez maksymalną liczbę plików w katalogu (1000) i stosujemy na niej floor.
Chciałem przetestować klase @Nospor-a, czy ktoś kto jej używa mógłby mnie naprowadzić gdzie mam zmienić zapis ścieżek tak jak napisał @wookieb o post wyżej?
Sam miałem dużo problemów z Cache, ten skrypt je rozwiązał. Dzięki nospor.
@rafalp wersja co ci wysłałem na maila zawiera miedzy innymi:
Sterownik bazujący na plikach pozwala zapisywac obiekty i grupy w postaci:
sciezka/do/obiektu
Tworzone zostają wówczas katalogi sciezka/do a w nich powstaje obiekt cache "obiektu".
Mozesz w ten sposob zarządzac struktura katalogów cache.
Mozesze czyscic wybrany katalog, czyscic raz na jakis czas oraz inne
Witam;
Właśnie próbuje ogarnąć tą klasę i prawdę mówiąc ciężko mi to idzie. Potrzebuję jakiegoś przykładu abym mógł się wzorować.
Niech przykładem będzie
W miejscu
$val = 'tutaj wyniki zapytania';
masz napisać zapytanie do pobierania danych z bazy, wykonać je (mysql_query()) a następnie wynik (tablica rekordow, obrobiony tekst czy co ty tam sobie zyczysz) zapisać w zmiennej $val
Coś takiego ?
Prawie dobrze.
Nie: $val =
a: $val .=
Widze, że robisz jako nazwe cache tresc zapytania. Zakladam więc, że włączyłeś hashowanie dla grupy @queries?
@nospor, powoli coś mi się udaje, wielkie dzięki. Tak, hashowanie mam włączone. Tylko jedno mnie dziwi. Po zaimplementowaniu cachu, z jednego zapytania - zrobiły się3
Jedno jest w :
Jakie 3? To ze nadales dla obiektu cache nazwę taką samą jak tresc zapytania to już nie moja wina. Mogles sobie obiekt cache nazwa "ala ma kota" i juz bys mial tylko jedno zapytanie
ALbo tresc zapytania wlozyc do zmiennej
$zm = 'SELECT dane FROM tabela LIMIT 0, 5';
I potem posługiwać się tylko zmienną.
Przecież to tylko przykład. Liczyłem, że osoby które to będą czytały wykażą się odrobiną no nie wiem, myslenia?
Wszystko działa jak należy. pomogłeś mi wiele zrozumieć, ale mam jeszcze jedno pytanko odnośnie organizacji plików cachu.
Chciałbym aby pliki danej grupy zapisywały się w oddzielnych folderach i widzę, że Twoja klasa to umożliwia - jednak nie do końca mi to działa ;/
Otóż owszem tworzy nowy folder, ale umieszcza w nim tylko plik @test
A, to przez to hashowanie
Cała nazwa obiektu "folder/nazwa" leci przez hash w wyniku czego znika folder/. No, o tym nie pomyślałem
Bardzo fajna i pożyteczna klasa, dziękuje.
W pliku example.php znalazłem coś takiego:
//Stworzenie grupy queries. Do niej beda wkladane wyniki zapytan. Id beda hashowane. //Obsluguje ja CacheFileDriver. Czas zycia 5 minut $cache->AddGroup('@queries', http://www.php.net/array( 'lifetime'=>300, 'driver'=>'fileDriver', 'hashid'=>true));
Jeśli chcesz kasować cache raz dziennie to za lifetime ustaw wartość 'day'
Jeśli chcesz kasować raz w miesiącu to ustaw 'month'
Co do każdego poniedziałku to póki co nie ma takiej opcji.
A jak powinien wyglądać kod usuwający cache 'kalendarz' z grupy @queries?
czy wystarczy:
require('Cache.class.php'); require('drivers/CacheFileDriver.class.php'); try { //stworzenie obiektu cache. $cache = new Cache(); $cache->AddDriver('fileDriver',new CacheFileDriver('Cache')); //Stworzenie grupy queries. Do niej beda wkladane wyniki zapytan. Id beda hashowane. //Obsluguje ja CacheFileDriver. Czas zycia 5 minut $cache->AddGroup('@queries', http://www.php.net/array( 'lifetime'=>300, 'driver'=>'fileDriver', 'hashid'=>true)); //Wyczyszczenie danego obiektu $cache->ClearObjects('kalendarz','@queries'); } catch (CacheException $e){ http://www.php.net/echo '<span style="color:red">'.$e->getMessage().'</span>'; }
W paczce masz podane kody do pobierania danych z cache. Gdy cache jest już nieaktualny to generujesz obiekt na nowo i wkładasz do cache. Wszystko to masz w paczce z przykładami. Musisz zrobić dokładnie tak samo jak tam jest podane.
Gdy ustawisz czas życia obiektu na 'day' to przy pobieraniu danych z cache dostaniesz NULL w przypadku gdy właśnie wskoczył nowy dzień. Postępowanie jest dokładnie takie samo jakbyś zamiast 'day' dał 300 sekund.
Właśnie o ten poniedziałek mi chodzi
No to ten cron powinien załatwić sprawę
ale ten kod który podałem wcześniej jest wystarczający?
czy
//Stworzenie grupy queries. Do niej beda wkladane wyniki zapytan. Id beda hashowane. //Obsluguje ja CacheFileDriver. Czas zycia 5 minut $cache->AddGroup('@queries', http://www.php.net/array( 'lifetime'=>300, 'driver'=>'fileDriver', 'hashid'=>true));
No tak, jak nie zdefiniujesz grupy z której usuwasz, to poleci wyjątek, że takiej grupy nie ma.
dzięki za podpowiedzi, tak się jeszcze zastanawiam jak działa ' 'lifetime'=>day, '
czy załóżmy jeśli cache zostanie utworzone dziś o 09:10 to jego czas wygasa o północy czy jutro 09:10?
bo jesli jutro 09:10 to też muszę je kasować cronem
Nie. cache z opcją day kasuje się dokładnie następnego dnia, niezależnie o której był utworzony dnia wcześniejszego.
A dokładnie kasowany jest dnia następnego przy pierwszej próbie jego pobrania. Jeśli pierwsza próba pobrania będzie o północy to skasuje się o północy. Jeśli pierwsza próba pobrania będzie o 02:34 to skasowany zostanie o 02:34
Więc chyba pozostaje mi czyszczenie cache imieninowego z crona, przecież jak ktoś wywoła pierwszy raz skrypt jednego dnia o 08:05 a drugiego o 7:02 to o mu się pokaże zawartość wczorajszego cache bo od czasu powstania nie minie 24h.
Dziękuje jeszcze raz za dokładne i rzeczowe wytłumaczenie.
NIe zrozumiałeś totalnie....
Przecież ci tłumaczę, że day nie oznacza 24h a oznacza nowy dzien.
Jeśli cache utworzy się o 08:05 a następnego dnia ktoś go wywoła o 07:02 to cache się wyczyści i wygeneruje na nowo z dniem aktualnym - będziesz więc miał to co chcesz.
Faktycznie, nie zrozumiałem.
to jeszcze spytam o jedna rzecz:
czy jak tak zdefiniujemy grupę w ten sposób:
$cache->AddGroup('@queries', http://www.php.net/array( 'driver'=>'fileDriver', 'hashid'=>true));
$val = $cache->Get('zapytanie_mysql', '@queries', 5);
Tak, gdy określisz czas w Get() to nadpisze on czas z grupy.
Gdy w grupie nie określisz czasu to zostanie przydzielony dla grupy czas domyślny.
Podsumowując: jest tak jak napisałeś
Czy da się tak ustawić aby Cache ogóle nie było kasowane Tzn tylko na życzenie. Np. podczas gdy dokonuje zmiany w bazie za pomocą kodu php = odpalić czyszczenie cache w przeciwnym wypadku cache nie jest w ogóle kasowane
Jaki parametr ma przyjść lifetime
Ustaw za lifetime np. 5 lat. Podejrzewam, że przez ten czas sam kilka razy skasujesz na żądanie
Bardzo fajna klasa Mam jednak problem z grupą "@queries".
Czy da się za pomocą tej klasy zrobić tak, abym dodawał do cache tylko sam wynik zapytania mysql_query() ?
yyyy, mysql_query() czy mysql_fetch_array()? Do cache zazwyczaj zapisuje się rekordy a nie wynik mysql_query.
Tutaj o tym pisałem:
http://forum.nospor.pl/projekty/cache/cache-baza-danych-ft252.html
chyba źle sprecyzowałem pytanie, ale dzięki za właściwą odpowiedź i gratuluję napisania świetnej klasy
nospor, czy ta klasa nadawała by się do trzymania danych typu:
W cache trzyma się dane, które przez dany okres czasu nie zmieniają się, a ich pozyskiwanie jest zasobożerne. Jeśli te dane takie są, to tak, można je trzymać w cache.
Mam problem z klasą.
Mianowicie zrobiłem sobie system komentarzy w ajaxie (lokalizacja pliku do odbierania danych: module/komentarz_ajax.php). Dałem w nim również funkcję czyszczenia cache dla podstrony, na której formularz został wywołany.
Po wywołaniu w pliku takiego kodu:
$cache->ClearObjects('statystyki','@stringi');
Jeśli jako ścieżkę do katalogu podajesz tak: Cache to jest to ścieżka względne i leci względem aktualnego katalogu. Stąd zapewne masz problem. Musisz więc podawać ścieżkę bezwględną
W jaki sposób można to zrobić?
Modyfikując kod:
$cache->AddDriver('fileDriver',new CacheFileDriver('Cache'));
Albo podajesz złą ścieżkę
Albo skrypt nie ma prawa tworzenia katalogu tam gdzie podajesz
Albo więc podaj prawidłową ścieżkę
Albo nadaj właściwe prawa na tej ścieżce
Albo utwórz katalog Cache ręcznie wówczas skrypt nie będzie musiał go tworzyć
Wydaje mi się, że problem leży tylko i wyłącznie w ścieżce - po prostu skrypt jakoś nie może się cofnąć do poprzedniego katalogu, gdzie jest folder z Cache i traktuje folder "module" jako folder główny.
Problem dotyczy tylko formularza z ajaxem. W jaki sposób można podać ścieżkę do cache?
Przecież ci napisałem: masz podać ścieżkę bezwzględną a nie względną. Gdy podasz ścieżkę bezwzględną, to problemu ze ścieżką na 100% nie bedzie.
ok, ale w którym miejscu się to ustawia ? (bo gdzie próbuję to ustawić, to nie działa) W "example" nie widzę nic o ustawaniu ścieżki. Wybacz, że tak Cię męczę ..
No tu to się ustawia:
$cache->AddDriver('fileDriver',new CacheFileDriver('Cache'));
Chcesz pełną ściezke to piszesz pełną sciezke:
$cache->AddDriver('fileDriver',new CacheFileDriver('pełnasciezkadotakalogu/Cache'));
Robiłem tak i coś takiego mi pokazało:
Fatal error: Uncaught exception 'CacheException' with message 'Can't create file/catalog: http://localhost/strony/skrypt/Cache' in C:\xampp\htdocs\strony\skrypt\class\drivers\CacheFileDriver.class.php on line 41
CacheException: Can't create file/catalog: http://localhost/strony/skrypt/Cache in C:\xampp\htdocs\strony\skrypt\class\drivers\CacheFileDriver.class.php on line 41
Czy może chodzi tutaj o podanie ścieżki na serwerze? (czy jak to się nazywa)
Wybacz, ciągle się uczę. Dzięki
Czy można liczyć na jakieś wskazówki jak podłączyć tą klasę do OPT v2?
1) Nie wiem jak wygląda OPT
2) Cache za bardzo z OPT nie ma nic wspólnego. cache generuje się przed skorzystaniem do OPT. Do OPT mogą trafiać dane zarówno z bazy jak i z cache.
Tworzę sobie swoją, znacznie prostszą klasę do cachowania, patrzyłem jak to zrobiłeś. Czy w CacheFileDriver w linii 62 zamiast
if ($objectValue === false || http://www.php.net/is_null($objectValue))
if ($objectValueS === false || http://www.php.net/is_null($objectValueS))
Ano powinno
Naszczeście serialize rzadko kiedy się nie udaje, więc błąd nie jest straszny, ale masz racje, jest
To jeszcze na wszelki wypadek linia 224
$res = http://www.php.net/rmdir($fileInfo->getPathname());
Hehe, nie, tym razem wszystko jest ok.
Spójrz pare linijek wyżej:
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirName), RecursiveIteratorIterator::CHILD_FIRST);
rekurencję mam tu
Bez bicia przyznaję się, że nie bawiłem się jeszcze nigdy iteratorami, więc nie domyśliłem się że ten zapis załatwia rekurencję
Hehe, ale słowo "Recursive" mogło dać ci trochę do myślenia
Świetna sprawa z tą klasą do cache. Wdrożenie nie jest przesadnie skomplikowane, co mi się podoba. Mam dwa pytania:
1. Jeśli załaduję jakieś dane do pamięci operacyjnej z czasem na 5 minut i później usunę plik php w którym wywołałem klasę z ładowaniem danych do pamięci, co się stanie? Zostaną te dane w pamięci czy zostaną one usunięte po 5 minutach? W przypadku cache z wykorzystaniem danych na dysku one zostają dopóki nie wywołam ponownie danego pliku php z daną grupą cache.
2. Chciałbym pewne dane ładować do pamięci operacyjnej i tutaj pojawia się kwestia tego co się stanie gdy zabraknie miejsca w pamięci operacyjnej serwera? Tak pozatym, w jaki sposób mogę zweryfikować ilość dostępnej pamięci?
Mówisz o sterowniku APC?
ad1) Będzie tak samo jak z plikiem
ad2) To apc zarządza tym. Gdy mu brakuje pamięci to.... nie pamiętam Kiedyś się bawiłem chyba na tę okazję, i jakoś sobie radził. Kasował stare wpisy czy może coś podobnego. Naprawdę teraz tego nie pamiętam.
Jaki jest maksymalny czas dla cache w pamięci i dyskowej? Mogę ustawić na przykład wartość 86400 (co będzie oznaczać 24 godziny), albo jeszcze więcej?
A możesz ustawić nawet i dwa lata jak masz taką ochotę
Witam,
Jestem początkujący i mam pytanie:
Pobieram dane i zapisuje je do pliku w kataogu np Cache/user/user_1/@queries
- dane zapisują się w pliku Cache a nazwy danych w Cache/user/user_1/@queries dlaczego dane nie zapisuję się tam gdzie nazwy danych?
- jeśli chcę wybrać folder w CacheFileDriver("Cache/user/user_1") który nie istnieje to nie tworzy go wyskakuje błąd, muszę sprawdzać czy plik istnieje tworzyć go i dopiero ustawiać ścieżkę w CacheFileDriver . Gdzie zmienić skrypt CacheFileDriver.class.php aby dodawał foldery automatycznie?
edit:
przy ustawieniu CacheFileDriver("Cache/user/user_1") wyskakuje błąd :
Warning: mkdir() [function.mkdir]: No such file or directory in /drivers/CacheFileDriver.class.php on line 39
Can't create file/catalog: Cache/user/user_1
Katalogi tworzą sie automatycznie. Widac skrypt nie ma prawa do tworzenia tam katalogow
Wiem przeglądałem kod i dziwi mnie że przy CacheFileDriver("Cache/user/user_1") wyskakuje błąd a przy $cache->AddGroup('user/user_1/@queries', array('lifetime'=>month, 'driver'=>'fileDriver','hashid'=>true)); i zapytaniu $data = $cache->Get($zapytanie1,'user/user_1/@queries'); tworzy katalogi i podkatalogi bez błędu.
Poniewaz CacheFIleDriver nie tworzy zagniezdzonych katalogow ,tylko co najwyzej jeden. Gdy tworzylem klase to w zamysle do cacheFIleDriver mialo sie zapodowac katalog glowny na cache, a dopiero grupy mogly sie zagniezdzac jak im sie podoba
Witam,
Zrobiłem test cache i wygląda, że jest 2x wolniejszy niż zapytania do bazy (baza ponad 130 000 wierszy.)
Zapytuję o 3 wartości w pętli 5000 razy.
Cache ma 4 pliki - zapytania i 3 pliki z danymi.
Zapytania do bazy to ok 4 sek.
Zapytania z cache to ok 8 sek.
Wydawało mi się, że z cache powinno lecieć szybciej.
Z czego wynika taka różnica
Pozdrawiam Jarek
Byłoby naprawde miło jakbyś uraczył nas kodem... skad mamy wiedziec gdzie lezy błąd.
Kod poniżej
require('Cache.class.php'); require('drivers/CacheFileDriver.class.php'); $db_server = 'localhost'; // server name $db_user = ''; // user name $db_pass = ''; // user password $db_name = 'baza'; // database name function getmicrotime() { $microtime = http://www.php.net/explode(' ', http://www.php.net/microtime()); return $microtime[1] . http://www.php.net/substr($microtime[0], 1); } function sql_connect($db_server, $db_user, $db_pass, $db_name) { if (http://www.php.net/mysql_connect($db_server , $db_user, $db_pass) and http://www.php.net/mysql_select_db($db_name)) { http://www.php.net/mysql_query("SET NAMES 'utf8'"); $status = true; } else { $status = false; } return $status; } // set_time_limit(1200); if(sql_connect($db_server, $db_user, $db_pass, $db_name)){ $data1 = http://www.php.net/array(92246,72682444,83043112); $ile = http://www.php.net/count($data1); $opcja = $_GET['o']; $time_start = getmicrotime(); if($opcja == 1){ try { //stworzenie obiektu cache. $cache = new Cache(); $cache->AddDriver('fileDriver',new CacheFileDriver('Cache')); $cache->AddGroup('@queries', http://www.php.net/array( 'lifetime'=>86400, 'driver'=>'fileDriver', 'hashid'=>true )); for($j=0;$j<5000;$j++){ for($i=0;$i<$ile;$i++){ $queries = "select * from katalog WHERE opcja = ".$data1[$i]; $val = $cache->Get($queries, '@queries'); if (http://www.php.net/is_null($val)){ $res = http://www.php.net/mysql_query($queries); $data = http://www.php.net/array(); while ($row = http://www.php.net/mysql_fetch_array($res)){$data[]= $row;} $cache->Put($queries, $data, '@queries'); } else { } } } } catch (CacheException $e){ http://www.php.net/echo '<span style="color:red">'.$e->getMessage().'</span>'; } } else { for($j=0;$j<5000;$j++){ for($i=0;$i<$ile;$i++){ $queries = "select * from katalog WHERE opcja = ".$data1[$i]; $res = http://www.php.net/mysql_query($queries); $data = http://www.php.net/array(); while ($row = http://www.php.net/mysql_fetch_array($res)){$data[]= $row;} } } } } $time_stop = getmicrotime(); $roznica = $time_stop - $time_start; http://www.php.net/echo 'Czas wczytywania pliku: ' . $roznica;
Może być szybsze przez to że MySQL robi cache zapytania, a że wykonujesz je xxxx razy pod rząd to już sobie z cache zasysa.
Dodaj SQL_NO_CACHE po SELECT.
Poza tym cache nadaje się do bardziej skomplikowanych zapytań niż zwykły select który pierdnie I w tym wypadku minimalizuje ilość zapytań samych w sobie, a nie szybkość (bo tu nie ma co przyspieszać)
1) Do cache powinno się wkładać raczej jakies wieksze kawałki, a nie malutkie pojedyncze rekordy
2) Do cache sie powinno wkladac dane, ktorych generowanie zajmuje stosunkowo duzo czasu a nie ułamek micro sekundy. W takim wypadku czasami cache nie ma sensu
Mi Twoj test wypada na korzysc cache, gdzie czas cache to ok 0.68420791625977 zas czas zapytan to ok 1.0938959121704
Oczywiscie wyniki te mogą być różne w zależnosci od posiadanego dysku, pamieci, procesora itp i moze sie okazac, że przy tak banalnych i szybkich zapytaniach, cache moze dzialac dluzej.
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)