0

I have a cron script that compresses images. It basically iterates over folders and then compresses the files in the folder. My problem is that some images are getting processed halfway. My theory is that users are uploading a image, and before the image has finished uploading the file, the compressor tries to compress the file. Thus compressing a half-uploaded image, and resulting in half an image being displayed.

  1. Is there a way in PHP to confirm that a file has finished uploading? So that I can only do the compression once i know the file has been fully written?
  2. Or alternatively, is there a way to check if a file is being used by another process?
  3. Or alternatively, would it be reliable enough to look at when the file was "written to disk" and not process it until 10 minutes has gone by?
rockstardev
  • 13,479
  • 39
  • 164
  • 296

3 Answers3

3

PHP doesn't trigger your action until the files are fully uploaded, but it is possible for your cron job to start interacting with files before they're fully saved.

When saving something from $_FILES, save it to a version with a . prefix on it to tag it as incomplete. Make sure your cron job skips any such files.

Then, once the save operation is complete, rename the file without the . prefix to make it eligible for processing.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • I know chances are probably small, but is there no change that the same could happen if the file didnt finish "moving"? – rockstardev Aug 14 '17 at 10:18
  • @coderama Renaming a file is an instantaneous operation, either it's not done or its done. Copying a file takes measurable time and during that time it's in the directory listing but incomplete, leading to the problems you're experiencing. – tadman Aug 14 '17 at 15:17
1

There are two ways to handle the scenario

Flags

Set flag that files before modify/write it. Our App handles lots of files, we set flags before taking them to process once it's done we remove the flag, as it runs on cron flag is the best way to process files.

Usually, you can an extra column on the table on each file. or you can have an array where you can store all currently handling files.

filemtime()

As you mentioned you can check like if file mtime is more than 10 min that current time, then you compress them but if some other processes are using the file opened the at the same time. it causes the problem again.

So its better to go with flag. If other processes never modify the files often.

Thamaraiselvam
  • 6,961
  • 8
  • 45
  • 71
1

You can use flock to ensure file is not in use, see here for example. Alternatively you can check whether an image is broken or corrupted see here.

vadim_hr
  • 533
  • 5
  • 11