2013-03-15 8 views
6

Mam formularz, który zapisuje dane wejściowe do pliku tekstowego. Czy możliwe jest zablokowanie pliku tekstowego do edycji, a może wydaje się przyjazny komunikat "plik jest edytowany przez innego użytkownika, spróbuj ponownie później."Plik tekstowy blokady PHP do edycji?

Chciałbym uniknąć konfliktów, jeśli plik ma wiele edytorów jednocześnie.

Oto, jak wpis jest aktualnie dodawany.

$content = file_get_contents("./file.csv"); 
$fh = fopen("./file.csv", "w"); 
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); 
fwrite($fh, "\n" . $content); 
fclose($fh);

Jakieś myśli?

+0

Nie znam metody na zrobienie tego, jednak możesz "stado" go, jeśli nie jesteś świadomy tej funkcji. Zapoznaj się z instrukcją PHP.net> http://php.net/manual/en/function.flock.php –

Odpowiedz

4

Możesz użyć funkcji flock(), aby zablokować plik. Dla bardziej zobaczyć this

coś takiego:

<?php 

     $content = file_get_contents("./file.csv"); 
     $fp = fopen("./file.csv", "w"); // open it for WRITING ("w") 
     if (flock($fp, LOCK_EX)) 
     { 
     // do your file writes here 
     fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); 
     fwrite($fh, "\n" . $content); 
     fclose($fh); 
     flock($fh, LOCK_UN); // unlock the file 
     } 
    ?> 
+2

Pomiędzy * fopen * i * flock * plik zostanie wyzerowany (z powodu dostępu 'w'), mam nadzieję, że to jest co chce OP ... Również odblokowanie powinno nastąpić przed zamknięciem pliku ... –

+0

Celem jest dodanie nowych linii do pliku, a nie resetowanie lub zastępowanie zawartości. – Janne

+1

@Janne, więc lepiej użyj dostępu 'a', a nie' w'. –

-1

chciałbym po prostu użyć prostego całkowitą lub coś podobnego.

$content = file_get_contents("./file.csv"); 
    $fh = fopen("./file.csv", "w"); 
    $status = 1; 

...  

if($status == 1){ 
    fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm); 
    fwrite($fh, "\n" . $content); 
    fclose($fh); 
    $status = 0; 
    } 
else 
    echo "the file is edited by another user, please try again later."; 

Czy to masz na myśli?

+0

'$ status = 1; if ($ status == 1) {'Chciałbym móc zrozumieć ten algorytm –

+0

@ ring0 lol Rozumiem, że nie jest to możliwe, aby zrobić to dokładnie tak, jak tam umieściłem. Może wcześniej lub masz funkcję checkStatus(). Gdzieś po prostu śledzi, czy użytkownik kliknął opcję edycji, i resetuje z powrotem do 0 po przesłaniu. Zrozumiałem, że powyższe jest technicznie niepoprawne. Przeprosiny – shanehoban

2

W kolejności pojawiania:

  1. używać bazy danych.
  2. Użyj więcej niż jednego pliku tekstowego.
  3. Zastosowanie locks:

np

$lockwait = 2;  // seconds to wait for lock 
$waittime = 250000; // microseconds to wait between lock attempts 
// 2s/250000us = 8 attempts. 
$myfile = '/path/to/file.txt'; 

if($fh = fopen($myfile, 'a')) { 
    $waitsum = 0; 
    // attempt to get exclusive, non-blocking lock 
    $locked = flock($fh, LOCK_EX | LOCK_NB); 
    while(!$locked && ($waitsum <= $lockwait)) { 
    $waitsum += $waittime/1000000; // microseconds to seconds 
    usleep($waittime); 
    $locked = flock($fh, LOCK_EX | LOCK_NB); 
    } 
    if(!$locked) { 
    echo "Could not lock $myfile for write within $lockwait seconds."; 
    } else { 
    // write out your data here 
    flock($fh, LOCK_UN); // ALWAYS unlock 
    } 
    fclose($fh);   // ALWAYS close your file handle 
} else { 
    echo "Could not open $myfile"; 
    exit 1; 
} 
1

Można użyć PHP's flock function aby zablokować plik na piśmie, ale że blokada nie będzie utrzymywać się w poprzek żądań internetowych i nie działa na NFS (przynajmniej z mojego doświadczenia).

Najlepszym rozwiązaniem może być utworzenie pliku tokena w tym samym katalogu, sprawdzenie jego istnienia i zgłoszenie błędu, jeśli istnieje.

Podobnie jak w przypadku każdego schematu blokowania, będziesz mieć warunki wyścigu i blokady, które pozostaną po zakończeniu operacji, więc będziesz potrzebował sposobu, aby je złagodzić.

Zalecam utworzenie skrótu pliku przed edycją i zapisaniem tej wartości w pliku blokady. Wyślij również skrót do klienta jako część formularza edycji (aby powrócił jako dane na żądanie zatwierdzenia). Przed zapisaniem porównaj przekazaną wartość skrótu do wartości w pliku. Jeśli są takie same, zatwierdz dane i usuń blokadę.

Jeśli są różne, pokaż błąd.

+0

Dlaczego blokada nie powinna występować w żądaniach internetowych? Blokady są na plikach, a nie deskryptorach (przynajmniej na Linuksie). –

+0

Czytałem, że fclose usuwa blokady, więc blokada będzie obowiązywać przez cały czas, gdy uchwyt pliku jest otwarty. Nie miałem szczęścia w uciekaniu się, więc staram się tego unikać. Myślę, że użycie pliku semafora w tym przypadku jest lepszym rozwiązaniem, ponieważ blokada powinna zostać uzyskana, gdy edycja jest uruchamiana i zwalniana, gdy jest już wykonana, co może być później kilkakrotnie przesyłane/sprawdzane/ponownie zgłaszane cykle. Nie próbuję uniknąć twojego pytania, po prostu nie mam dobrej odpowiedzi. –

+0

Nie, funkcja flock c (której php używa flok) działa na deskryptorach. http://linux.die.net/man/2/flock – symcbean

Powiązane problemy