Reputation: 2720
Does the flock()
function only work if it is used within the same method that the code is executed?
For example, in the following code, the lock is successful:
public function run()
{
$filePointerResource = fopen('/tmp/lock.txt', 'w');
if (flock($filePointerResource, LOCK_EX)) {
sleep(10);
} else {
exit('Could not get lock!');
}
}
However, in the following code, the lock is unsuccessful:
public function run()
{
if ($this->lockFile()) {
sleep(10);
} else {
exit('Could not get lock!');
}
}
private function lockFile()
{
$filePointerResource = fopen('/tmp/lock.txt', 'w');
return flock($filePointerResource, LOCK_EX);
}
I haven't seen any documentation on this, so I am puzzled by this behavior. I am using php version 5.5.35.
Upvotes: 2
Views: 321
Reputation: 94642
I think the issue with your class based attempt is that when the lockFile
method finishes the $filePointerResource
goes out of scope and that is probably what is releasing the lock
This works which sort of supports that theory
<?php
class test {
public function run()
{
$fp = fopen('lock.txt', 'w');
if ($this->lockFile($fp)) {
echo 'got a lock'.PHP_EOL;
sleep(5);
}
/*
* Not going to do anything as the attempt to lock EX will
* block until a lock can be gained
else {
exit('Could not get lock!'.PHP_EOL);
}
*/
}
private function lockFile($fp)
{
return flock($fp, LOCK_EX);
}
}
$t = new test();
$t->run();
So if you want to lock the file over more than one call to a class method it might be better to keep the filehandle as a class property, then it will remain in scope as long as the class is instantiated and in scope.
<?php
class test {
private $fp;
public function run()
{
$this->fp = fopen('lock.txt', 'w');
if ($this->lockFile()) {
echo 'got a lock'.PHP_EOL;
sleep(5);
}
/*
* Not going to do anything as the attempt to lock EX will
* block until a lock can be gained
else {
exit('Could not get lock!'.PHP_EOL);
}
*/
}
private function lockFile()
{
return flock($this->fp, LOCK_EX);
}
}
$t = new test();
$t->run();
Upvotes: 4