2011-07-21 4 views
0

Lorsqu'un utilisateur télécharger un fichier (les utilisateurs peuvent télécharger plusieurs fichiers)fichiers de verrouillage en PHP sans utiliser troupeau

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

J'utilise nohup comme il doit être exécuté à l'arrière.

Dans ma conception originale run.php scanne le répertoire en utilisant scandir chaque fois qu'il est exécuté. Obtenez un verrou exclusif LOCK_EX sur le fichier en utilisant flock et utilisez LOCK_NB pour ignorer le fichier s'il a un verrou et passez à la suivante. Si un fichier a un verrou //Do logic. Le problème est que le serveur est absent bibliothèque fcntl() et que flock utilise cette bibliothèque pour exécuter le mécanisme de verrouillage, flock ne fonctionnera pas pour le moment. Ça va prendre un mois ou deux pour l'installer (je n'ai aucun contrôle sur ça). Donc, mon travail pour cela est d'avoir un fichier temporaire lock.txt qui agit comme un verrou. Si le nom de fichier existe dans lock.txt, ignorez le fichier et passez au fichier suivant.

$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 
    } 
} 

Comment puis-je supprimer le nom de fichier de lock.txt?

Plus important encore, existe-t-il un meilleur moyen de verrouiller un fichier en php sans utiliser flock? Avoir une base de données de verrous partagés déplace simplement le problème de verrouillage vers ce fichier;

+1

Votre méthode pour exécuter le processus backlground est défectueuse - voir http://symcbean.blogspot.com/2010/02/php-and-long-running-processes.html – symcbean

+0

merci pour cela :) – theking963

Répondre

1

ça ne le résout pas.

Une meilleure solution consiste à utiliser un fichier de verrouillage par fichier réel. Si vous voulez verrouiller l'accès à myFile.csv alors vous vérifiez file_exists('myFile.csv.lock') et touch('myFile.csv.lock') s'il n'existe pas. Et unlink('myFile.csv.lock') une fois terminé.

Maintenant, il existe une condition de concurrence possible entre file_exists() et touch(), qui peut être atténuée en stockant le PID dans le fichier et en vérifiant si getmypid() est bien le processus qui détient le verrou.

Questions connexes