file_put_contents access denied inside a loop

118 Views Asked by At

Today, I were updating some legacy code. It was some vanilla PHP small application with ajax queries to export data from database.

The application allows you to select a type of data you want to extract, you click on "Export" button, it posts an Ajax query that will query a database and writes the result in a .xlsx file.

The previous developer made a system to display a progress bar while the export is being written. A system I have never seen nor thought.

He has made a jQuery function, that will read a .txt file that contains the number of elements being processed, example :

1205/15000

The function :

$.get( "./suivis/" + <?php echo $idUser ?>+"_suivis.txt", function( data ) {
    if(data === "save"){
        $("#results").html('<p>Creating Excel file, thank you for waiting.</p>' );
    }

    var elem = data.split('/');
    if( elem[0] != '' &&   elem[1] != '' && data != "save")
    {
        $("#results").html(  '<progress value="'+elem[0]+'" max="'+elem[1]+'"></progress>' );

    }
})

So he uses the content of the .txt file to manage the progress bar. That function is called every 0.5 seconds.

Now, on the part of the script executed by the Ajax query, we query the database, count the array of results to get the total of lines to write, create a counter for the foreach, and while we write the .xlsx file, we also do :

$current = ($i-1).'/'.$total;
file_put_contents($file, $current);

That's how we write the processing state in the .txt file.

The error I got, happened only when I had many lines being written (more than 10K). Once during the process, I'd randomly get (around 5K / 7K) an error from file_put_contents function : failed to open stream. Permission denied.

I have two guesses about why it's happening.

First : It may be because I'm getting it's content with Jquery every 0.5 seconds, and opening, writing and closing it really fast inside a foreach loop. Maybe that the file is "locked" while Jquery accesses its content and PHP can't open it at the same time. Many lines being processed would mean a greater probability that this issue could happen.

Second : It's more unlikely, but maybe doing too manies file_put_contents in a row, could make the system struggle and would try to open and write while the file is still not closed. But as file_put_contents is a wrapper for open, write, close, I doubt it, but who knows, I'm not an expert.

I eventually "fixed" the problem, at least it's not showing anymore for the volume I treat, by making it write the .txt file every 200 records instead of every record.

What do you think is happening ? Is my first guess correct ? Do you see any better approach ?

Thank you for your insights.

0

There are 0 best solutions below