Блокировка файлов в PHP без использования flock - PullRequest
0 голосов
/ 21 июля 2011

Когда пользователь загружает файл (пользователи могут загружать несколько файлов)

exec('nohup php /main/apache2/work/upload/run.php &');

Я использую nohup, так как он должен быть выполнен в серверной части.

В моем оригинальном дизайне run.php сканирует каталог, используя scandir каждый раз, когда он выполняется.Получите эксклюзивную блокировку LOCK_EX для файла с помощью flock и используйте LOCK_NB, чтобы пропустить файл, если он имеет блокировку, и перейти к следующей.Если файл имеет блокировку //Do logic.Проблема в том, что на сервере отсутствует библиотека fcntl(), и поскольку flock использует эту библиотеку для выполнения механизма блокировки, flock не будет работать в данный момент.Это займет месяц или два, чтобы установить его (я не могу это контролировать).

Так что моя работа в этом направлении - временный файл lock.txt, который выполняет блокировку.Если имя файла существует в lock.txt, пропустите файл и перейдите к следующему.

$dir = "/main/apache2/work/upload/files/";
$files = scandir($dir);
$fileName = "lock.txt";

for($i=0; $i<count($files); $i++) 
{   
    if(substr(strrchr($files[$i],'.csv'),-4) == '.csv')
    {           
        if($file_handle = fopen("$fileName", "rb"))
        {
            while(!feof($file_handle))
            {
                $line = fgets($file_handle);
                $line = rtrim($line);
                if($line == "")
                {
                    break;
                }
                else
                {
                    if($files[$i] == $line)
                    {
                        echo "Reading from lock: ".$line."</br>";
                        $i++; //Go to next file
                    }
                }

            }
            fclose($file_handle);
        }

        if($i >= count($files))
        {
            die("$i End of file");
        }

        if($file_handle = fopen("$fileName", "a+"))
        {
            if(is_writable($fileName))
            {               
                $write = fputs($file_handle, "$files[$i]"."\n");
                //Do logic

                //Delete the file name - Stuck here

                fclose($file_handle);
            }

        }

    }
    else
    {
        //Do nothing
    }
}

Как удалить имя файла из lock.txt?

Что более важно, есть ли лучший способ заблокировать файл в php без использования flock?

1 Ответ

1 голос
/ 21 июля 2011

Наличие базы данных с общей блокировкой просто перемещает проблему блокировки в этот файл;это не решает проблему.

Гораздо лучшим решением является использование одного файла блокировки для каждого реального файла.Если вы хотите заблокировать доступ к myFile.csv, тогда вы проверяете file_exists('myFile.csv.lock') и touch('myFile.csv.lock'), если он не существует.И unlink('myFile.csv.lock') когда это будет сделано.

Теперь существует возможное состояние гонки между file_exists () и touch (), которое можно смягчить, сохранив PID в файле и проверив, действительно ли getmypid()процесс, удерживающий блокировку.

...