80 likes | 226 Views
Flock in PHP. By Chao Liang. Basic Flock Concept. What is flock? Abbreviation for file locking Why flock? Data consistency. Prevent file corruption. Different types of flock Advisory Mandatory. Flock in PHP. Availability: PHP 3 >= 3.0.7, PHP 4, PHP 5
E N D
Flock in PHP By Chao Liang
Basic Flock Concept • What is flock? • Abbreviation for file locking • Why flock? • Data consistency. • Prevent file corruption. • Different types of flock • Advisory • Mandatory
Flock in PHP • Availability: • PHP 3 >= 3.0.7, PHP 4, PHP 5 • Advisory in Unix by default, and Mandatory in Windows • Syntax: • bool flock ( resource handle, int operation [, int &wouldblock] ) • Handle: open file pointer • Operation: • LOCK_SH - shared lock • LOCK_EX - exclusive lock • LOCK_UN - release lock • LOCK_NB - no block while locking • Optional: • $wouldblock – true if blocked, usually used with LOCK_NB • Return: • True for success • False for failure
Before Use Flock • By default, LOCK_SH, LOCK_EX, and LOCK_UN are blocked. • LOCK_SH can be held by more than one process while LOCK_EX can only held by a single one process. • A typical use for flock would be try to append to a log file. • Request a shared lock when you only need to read from the file. • Request an exclusive lock when you need to write to the file. • Every file write operation needs to use the same locking mechanism in order for flock to work correctly. • Use a database if more stability and security required. • Do not forget to release the exclusive lock, or others can not get the lock.
Example 2: <?php $writeSuccess = false; $fp = fopen(“./test.txt", "w+"); while($fp && !$writeSucess){ $writeSucess = flock($fp, LOCK_EX)); usleep(round(rand(0,10000))); } if (!$fp) {exit;} fwrite($fp, “Lock and write"); flock($fp, LOCK_UN); fclose($fp); ?> Example 1: <?php $fp = fopen(“./test.txt", "w+"); flock($fp, LOCK_EX)) fwrite($fp, “Lock and write"); flock($fp, LOCK_UN); fclose($fp); ?> How to Use Flock Request exclusive lock Avoid collision Avoid invalid file pointer Block if other has the lock No statements inin between to minimize the chance of data lost Release lock
Blocking can introduce data lost due to fopen does not do file locking. In Linux, flock can return false, even if locking succeeds. Fix: use LOCK_NB and $wouldblock <?php do { if(isset($wouldlock)) { flock($fp,LOCK_UN); fclose($fp); } $fp=fopen(“./test.txt","a") or die(); flock($fp,LOCK_EX | LOCK_NB,$wouldblock); usleep(round(rand(0,10000))); }while ($wouldblock ==1);fwrite($fp, “Begin writing”);flock($lock,LOCK_UN);fclose($fp); ?> How to Use Flock Cont. Ignore the return since it is not reliable Locking without blocking Locking succeed condition
Use mkdir($file.lock) to simulate flock($file, LOCK_EX), and rmdir($file.lock) to simulate flock($file, LOCK_UN). Example: <?php $fp = fopen(“./test.txt”, ‘a’); Do{ $locked = @mkdir(“test.txt.lock”); usleep(round(rand(0,10000))); } while ($locked === false); fwrite($fp, “begin writing”); rmdir(“test.txt.lock”); ?> Workaround for Flock in NFS It will fail if directory existsto indicate file is locked Removing the directory actsjust like releasing the lock
Limitation of Flock • Flock does not work for NFS. • Downgrades release the old lock before applying the new lock. • Flock does not support for FAT file system. • Flock is not reliable for multithread server. • Flock is handled differently among Windows, Linux, and Unix: advisory in Unix and Linux, and mandatory in Windows. • Other process can still write to the file if it does not request a lock before writing to it.