Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]fileatime i nie zmieniający się czas.
Forum PHP.pl > Forum > Przedszkole
Kużdo
Witam,

Mam problem z funkcją fileatime, ponieważ sprawdzałem już na kilku hostingach (w tym localhost) i na żadnym z nich czas nie zmieniał się pomimo otwierania pliku w przeglądarce. Sprawdzałem nawet otwierając plik normalnie w środowisku, czy edytując go. Zmieniał się tylko czas z filemtime. Chciałem zrobić hosting obrazków na potrzeby małej grupki osób i zainteresowałem się tą funkcją, ponieważ chciałem zrobić to tak, że pliki byłyby kasowane np. 30 dni po ostatnim ich obejrzeniu. Ale nie wiem jak pobierać czas, skoro ten czas się nie zmienia. Są do tego jakieś inne funkcje?

Pozdrawiam
CuteOne
Niektóre unix'owe systemy plików mogą być montowane z wyłączonym uaktualnianiem czasu dostępu, aby podnieść wydajność takich aplikacji
abort
Z manuala:
Kod
The results of this function are cached. See clearstatcache() for more details.


Może tu jest problem?
Kużdo
@CuteOne: Serwer dedykowany, serwer hostingu + serwer domowy na windowsie = ten sam efekt.

@abort, o tym pamiętałem i niestety, ale nie w tym leży problem sad.gif

Nikt nie wie co może być przyczyną lub czy są jakieś lepsze funkcje od tych?

Ponawiam pytanie jeszcze raz, bo to dosyć ważne.
abort
Po głębszym przyjrzeniu się problemowi okazało się, że także u mnie zarówno fileatime, jak i stat zachowują się, delikatnie mówiąc, dziwnie. W związku z tym zacząłem zgłębiać temat, przy czym ograniczyłem się do Linuksa (co nie powinno być problemem, bo większość hostingów i vpsów to jakiś tam Linux).
Okazało się, że za taki "dziwny" stan rzeczy (taki jak Ty opisujesz, jak i taki jak ja zauważyłem), odpowiada... kernel Linuksa. Niemniej, da się go przekonać, by działał tak jak trzeba. Ale po kolei. Mając filesystem zamontowany z domyślnymi opcjami działa to jak w opisie. Domyślne opcje to u mnie (z /proc/mounts):
Kod
/[device] /[mountpoint] ext3 rw,relatime,errors=continue,data=ordered 0 0

Wczytując się w manual do atime, znalazłem:
Kod
       atime  Update  inode access time for each access. See also the stricta-
              time mount option.

       noatime
              Do not update inode access times on this  filesystem  (e.g,  for
              faster access on the news spool to speed up news servers).

       relatime
              Update  inode  access  times  relative to modify or change time.
              Access time is only updated if the previous access time was ear-
              lier  than  the current modify or change time. (Similar to noat-
              ime, but doesn't break mutt or other applications that  need  to
              know  if  a  file has been read since the last time it was modi-
              fied.)

       norelatime
              Do not use relatime feature.  See  also  the  strictatime  mount
              option.

       strictatime
              Allows  to  explicitly requesting full atime updates. This makes
              it possible for kernel to defaults to relatime  or  noatime  but
              still allow userspace to override it. For more details about the
              default system mount options see /proc/mounts.

       nostrictatime
              Use  the  kernel's  default  behaviour  for  inode  access  time
              updates.


Rozwiązaniem jest przemontowanie filesystemu z opcją "strictatime":
Kod
mount -o remount,strictatime [device|katalog]


U mnie pomogło, a efekt w /proc/mounts jest taki, że zniknęło "relatime":
Kod
/[device] /[mountpoint] ext3 rw,errors=continue,data=ordered 0 0



Potestuj.
Crozin
Tak na marginesie: w ogóle nie powinieneś tutaj korzystać z systemowego czasu dostępu do pliku. Całość powinieneś monitorować po stronie aplikacji, tj. przy każdym dostępie do pliku aktualizować sobie w bazie danych czas ostatniego dostępu. Co za tym idzie listę plików do skasowania pobierałbyś z bazy, nie latając po każdym pliku (których mogą być miliony) i sprawdzając czas ostatniego dostępu.
abort
@Crozin: oczywiście, w 100% racja. Na marginesie: jeśli nie ma bazy (bo nie może być albo gdy to jest overkill), to można to zrobić na plikach: dla pliku "image.jpg" tworzymy "image.txt" i przy każdych odwiedzinach dopisujemy do tego pliku JEDEN ZNAK. I już mamy załatwione dwie najważniejsze rzeczy, o których autor pisał, czyli czas ostatniego obejrzenia obrazka (bo to jest czas modyfikacji pliku txt - a czas modyfikacji AFAIK BĘDZIE uaktualniany). Mamy tez ilość odwiedzin (jest to po prostu długość pliku).
Kużdo
A w przypadku, gdy chcę ograniczyć życie pliku do 30 dni, ale osoby korzystające z serwisu będą otwierały go bezpośrednio (tzn. nie przez jakiś skrypt/html) to jak mam dodawać do bazy odczyt, skoro interpreter tutaj w ogóle nie będzie brał udziału?
Crozin
Bardzo prosto: nie umożliwiaj bezpośredniego* dostępu do pliku. Zawsze serwuj go przez pośredniczący skrypt, który będzie aktualizował metadane odnośnie pliku (m.in. czas ostatniego dostępu), sprawdzał jakieś uprawnienia dostępu, logował informacje, zapisywał statystyki, ograniczał prędkość przesyłu danych czy robił cokolwiek innego czego sobie zażyczysz.

* bezpośredni jak bezpośredni, zawsze plik musi przejść przez serwer HTTP.
Kużdo
Hmm, w sumię mogę chyba serwować pliki nawet przez php jak gdyby to było zwykłe odwołanie do pliku i tak chyba to zrobię.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.