Block function in php for one user only

Hi I have a php function, it takes about 20 minutes (or more) to run and complete.

but if someone else runs it during the last run ... The function is aborted with unwanted result.

these are structures:

function myfunc()
{
   foreach()
   {
      //do somthing
   }
}

      

I think I can do it via a file like this:

I created a text file ... if the content of this text was "1", the function is blocked. if not the function is free.

function myfunc()
{
    $file = "lock.txt";
    $f = fopen($file, 'r');
    $line = fgets($f); 
    fclose($f);
    if($line == 0)
        file_put_contents($file, "1");
    else 
        return false;

    foreach()
    {
    }

    //after finish for each
    file_put_contents($file, "0"); // free function for other user 
}

      

I think logically it should be true ... but doesn't work! after the first run, the contents of the lock.txt file remains at 1. (does not change to 0 after the end)

I think maybe the function breaks during the process due to the long time! because I handle all the break state in the function. can you call me how to deal with this problem? how can I be sure that lock.txt will be "0" after the terminate or interrupt function?

+3


source to share


4 answers


Well, there is already a function to implement lock. Flock () is called

<?php

$file = fopen("test.txt","w+");

// exclusive lock
if (flock($file,LOCK_EX))
  {
  fwrite($file,"Write something");
  // release lock
  flock($file,LOCK_UN);
  }
else
  {
  echo "Error locking file!";
  }

fclose($file);
?> 

      



with the LOCK_SH flag you can lock it

+1


source


Fortunately, the best way in my experience is like this

<?php

define('LOCK_FILE', "/var/run/" . basename($argv[0], ".php") . ".lock");

if (!tryLock())
    die("Already running.\n");

 # remove the lock on exit (Control+C doesn't count as 'exit'?)
register_shutdown_function('unlink', LOCK_FILE);

# The rest of your script goes here....
echo "Hello world!\n";
sleep(30);

exit(0);

 function tryLock()
{
     # If lock file exists, check if stale.  If exists and is not stale, return TRUE
     # Else, create lock file and return FALSE.

    if (@symlink("/proc/" . getmypid(), LOCK_FILE) !== FALSE) # the @ in front of 'symlink' is to suppress the NOTICE you get if the LOCK_FILE exists
        return true;

    # link already exists
    # check if it stale
    if (is_link(LOCK_FILE) && !is_dir(LOCK_FILE))
    {
        unlink(LOCK_FILE);
        # try to lock again
        return tryLock();
    }

    return false;
}
?>

      

Taken from comments



http://php.net/manual/en/function.getmypid.php

This blocks the process, so if the process fails, you can remove the lock

0


source


Thanks to my friends for the answer.

I couldn't run your code ... maybe because I can't set them up correctly ...

but I solved the problem of inserting the insile code function like this:

$file = "lock.txt";
$f = fopen($file, 'r');
$line = fgets($f); 
fclose($f);
if($line == 0)
{
    file_put_contents($file, "1");
    myfunction();
    file_put_contents($file, "0");
}
else
{
    echo "Already running.";
}

      

hope help someone else ...

0


source


I use these functions (for example, I call them my_lock and my_unlock):

function my_lock($name) {
    $lockFile = 'myfolder/' . $name . '.lck';
    $lock = fopen($lockFile, 'w');
    if (!$lock) {
        return false;
    }
    if (flock($lock, LOCK_EX)) {
        return $lock;
    } else {
        fclose($lock);
        return false;
    }
}

function my_unlock($lock) {
    if ($lock !== false) {
        flock($lock, LOCK_UN);
        fclose($lock);
    }
}

      

example of use:

    $lock = my_lock('hello_world');
    if ($lock === false) {
      throw new Exception('Lock error');
    }
    try {
      //... your locked code here ...
    } finally {
      my_unlock($lock);
    }

      

0


source







All Articles