skip to Main Content

My centos cron-job code reads the local file and sometimes gets an empty string, but I never write an empty string to that file.

/*
 * in a cron job
 */

// verify that the file exists
if (!file_exists($my_file_path))        // if the file does Not exist
{                                       // then error
    error_log("file does Not exist");
    exit();
}

// read the file contents
$file_contents = file_get_contents($my_file_path);

// check result
if ($file_contents === false)           // if read failed
{                                       // then error
    error_log("file_contents === false");
    exit();
}

// look for empty string
if ($file_contents === '')              // if contents is empty string
{                                       // then check again after sleep
    error_log("file_contents === ''");
    sleep(1);
    $file_contents = file_get_contents($my_file_path);
    if ($file_contents === false)           // if read failed
    {                                       // then error
        error_log("file_contents === false, after sleep");
        exit();
    }
    if ($file_contents === '')              // if contents is still empty
    {                                       // then log it and exit
        error_log("file_contents is still empty, after sleep");
        exit();
    }
    else                                    // else contents Now Exists
    {                                       // so log it and use contents
        error_log("file_contents Exists, after sleep: $file_contents");
    }
}

In two places I write to the file:

// write the file contents
file_put_contents($my_file_path, time());

In one place I can remove the file (but I checked, and this code is Not being executed):

// remove the file
unlink($my_file_path);

I can’t see how file_get_contents should ever give me an empty string, even if it was being unlinked.

2

Answers


  1. Chosen as BEST ANSWER

    NVRM had the answer. I had a race condition between the file_put_contents() operation and the file_get_contents() operation. I did not know that the file_put_contents() was not an atomic operation, even when it is "write" and not "append".

    There are a number of ways I could have fixed my code. Here's 2:

    • use flock
    • write to a temporary file and then use rename (because rename is ataomic)

    Mine is a special, very simple, case where I just need to share a timestamp between my webpage scripts and a cron-job. So I ditched the use of file_put_contents() and file_get_contents() and replaced that code with touch() and filemtime().


  2. Try using the complete path to your file /var/www/html/.... /your_doc.php this can help you

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search