Ли flock()
Функция работает, только если она используется в том же методе, что и код?
Например, в следующем коде блокировка успешна:
public function run()
{
$filePointerResource = fopen('/tmp/lock.txt', 'w');
if (flock($filePointerResource, LOCK_EX)) {
sleep(10);
} else {
exit('Could not get lock!');
}
}
Однако в следующем коде блокировка не удалась:
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);
}
Я не видел никакой документации по этому вопросу, поэтому я озадачен этим поведением. Я использую PHP версии 5.5.35.
Я думаю, что проблема с вашей попыткой на основе класса заключается в том, что когда lockFile
метод заканчивает $filePointerResource
выходит из области видимости, и это, вероятно, то, что снимает блокировку
Это работает, что поддерживает эту теорию
<?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();
Поэтому, если вы хотите заблокировать файл более чем одним вызовом метода класса, может быть лучше сохранить дескриптор файла как свойство класса, тогда он останется в области действия, пока создается экземпляр класса и в области действия.
<?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();
Других решений пока нет …