Rozdział 7. ♦ System plików 207
już w przypadku skryptu obsługującego zamówienia w sklepie internetowym konsekwencje mogą być poważne. Jak zatem rozwiązać ten problem? Najlepiej zamiast zapisywać dane w plikach, wykorzystać system bazy danych, taki jak np. omówiony w dalszej części książki MySQL. Jeśli jednak koniecznie musimy użyć plików, można do synchronizacji dostępu do pliku posłużyć się funkcją flock.
Wywołanie funkcji flock powoduje założenie blokady na dany plik, takiej że dostęp do niego będzie miał tylko skrypt, który tę funkcję wywołał. Wywołanie to ma postać: flock(deskryptor. operacjal. blokowanie])
gdzie deskryptor to deskryptor pliku zwrócony przez funkcję fopen, operacja określa rodzaj blokowania. Z kolei blokowanie to opcjonalny parametr (typu boolean) określający, czy w przypadku kiedy blokada w danym momencie nie może być uzyskana, funkcja ma czekać, aż blokada będzie możliwa (blokowanie = true), czy też od razu zakończyć działanie (blokowanie = false). Funkcja zwraca wartość true, jeżeli udało się uzyskać blokadę, lub też wartość fal se — w przeciwnym wypadku.
Parametr tryb może przyjmować następujące argumenty:
♦ L0CK_SH (lub 1 dla PHP wersji poniżej 4.0.1) — blokada zapisu, możliwy odczyt przez wiele procesów,
♦ L0CK_EX (lub 2 dla PHP wersji poniżej 4.0.1) — pełna blokada,
♦ LOCKJJN (lub 3 dla PHP wersji poniżej 4.0.1) — zwolnienie blokady,
♦ L0CK_NB (lub 4 dla PHP wersji poniżej 4.0.1) — dodanie wartości L0CK_NB do parametru operacja powoduje, że w razie niemożności założenia blokady funkcja kończy działanie.
Schematyczny kod wykorzystujący flock do blokady zapisu do pliku będzie miał postać: <?php
if(!$fd = fopenCtest.txt'. 'a')) exit(”Nie mogę otworzyć pliku test.txt"): i f<!flock($fd. L0CK_EX)) exit(“Nie mogę założyć blokady pliku test.txt"):
//operacje na pliku
1f(!flock($fd. LOCKJJN)) exit(”Nie mogę zdjąć blokady pliku test.txt"): fclose($fd):
Korzystając z flock należy pamiętać, że nie działa ona poprawnie w systemie NFS i większości innych rozproszonych systemów plików. W niektórych systemach flock może być zaimplementowana na poziomie procesu, co oznacza, że jeżeli wywołania poszczególnych instancji skryptu odbywają się w różnych procesach, funkcja nie będzie działała poprawnie (do takiej sytuacji dojdzie np. podczas korzystania z ISAPI). Funkcja flock nie funkcjonuje również w przypadku przestarzałych systemów plików, jak np. FAT.