note 109237 modified in function.flock by danbrown
| From: | danbrown@php.net | Date: | Mon, 16 Jul 2012 16:03:32 +0000 |
| Subject: | note 109237 modified in function.flock by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-189245@lists.php.net to get a copy of this message | ||
I just spent some time (again) to understand why a reading with file_get_contents() and file was
returning me an empty string "" or array() whereas the file was existing and the
contents not empty. In fact, i was locking file when writing it
(file_put_contents third arg) but not testing if file was locked when reading it (and the file was
accessed a lot). So, please pay attention that
file_get_contents(), file() and maybe others php files functions are going to return empty data like
if the contents of the file was an empty string. To avoid this
problem, you have to set a LOCK_SH on your file before reading it (and then waiting if
locked). Something like this
: <?php public static function
getContents($path, $waitIfLocked = true) { 	if(!file_exists($path))
{ 		throw new Exception('File
"'.$path.'" does not
exists'); 	} 	else
{ 		$fo = fopen($path,
'r'); 		$locked = flock($fo, LOCK_SH,
$waitIfLocked); 		 		if(!$locked)
{ 			return
false; 		} 		else
{ 			$cts =
file_get_contents($path); 			 			flock($fo,
LOCK_UN); 			fclose($fo); 			 			return
$cts; 		} 	} } ?> Code
to test by yourself : abc.txt
: someText file.php
: <?php $fo = fopen('abc.txt',
'r+'); flock($fo,
LOCK_EX); sleep(10); flock($fo,
LOCK_UN); ?> file2.php :
<?php var_dump(file_get_contents('abc.txt')); var_dump(file('abc.txt')); ?> Then
launch file.php and switch to file2.php during the 10 seconds and see the difference before/after
--was--
I just spent some time (again) to understand why a reading with file_get_contents() and file was
returning me an empty string "" or array() whereas the file was existing and the contents
not empty.
In fact, i was locking file when writing it (file_put_contents third arg) but not testing if file
was locked when reading it (and the file was accessed a lot).
So, please pay attention that file_get_contents(), file() and maybe others php files functions are
going to return empty data like if the contents of the file was an empty string.
To avoid this problem, you have to set a LOCK_SH on your file before reading it (and then waiting if
locked).
Something like this :
public static function getContents($path, $waitIfLocked = true) {
if(!file_exists($path)) {
throw new Exception('File "'.$path.'" does not exists');
}
else {
$fo = fopen($path, 'r');
$locked = flock($fo, LOCK_SH, $waitIfLocked);
if(!$locked) {
return false;
}
else {
$cts = file_get_contents($path);
flock($fo, LOCK_UN);
fclose($fo);
return $cts;
}
}
}
Code to test by yourself :
abc.txt :
someText
file.php :
$fo = fopen('abc.txt', 'r+');
flock($fo, LOCK_EX);
sleep(10);
flock($fo, LOCK_UN);
file2.php :
var_dump(file_get_contents('abc.txt'));
var_dump(file('abc.txt'));
Then launch file.php and switch to file2.php during the 10 seconds and see the difference
before/after
http://php.net/manual/en/function.flock.php