PHP Script for Monitoring Folder Creation - php

I want to write one PHP script that will tell me how many folders getting created today( not modified one !! ).
Ex. Suppose if gave the path ( like c:\Data ) so my script must be continuously checking that
give path for if it is new entry of any folder. I have used http://php.net/manual/en/function.date-diff.php. But getting result for modified folders as well.

Quote from #Alin Purcaru:
Use filectime. For Windows it will return the creation time, and for Unix the change time which is the best you can get because on Unix there is no creation time (in most filesystems).
Using a reference file to compare the files age allows you to detect new files whidout using a database.
// Path to the reference file.
// All files newer than this will be treated as new
$referenceFile="c:\Data\ref";
// Location to search for new folders
$dirsLocation="c:\Data\*";
// Get modification date of reference file
if (file_exists($referenceFile))
$referenceTime = fileatime($referenceFile);
else
$referenceTime = 0;
// Compare each directory with the reference file
foreach(glob($dirsLocation, GLOB_ONLYDIR) as $dir) {
if (filectime($dir) > $referenceTime)
echo $dir . " is new!";
}
// Update modification date of the reference file
touch($referenceFile);
Another solution could be to use a database. Any folders that are not in the database are new. This ensures to not catch modified folders.

You might want to try getting your script launched with cron like every one minute and check the difference between directory lists (from before and current I mean), not the dates. It's not a perfect solution, but it will work.
Check directories arays with:
$dirs = array_filter(glob('*'), 'is_dir');
Compare them later with array_diff

Related

PHP - select ONLY file in folder without foreach()?

I have a script that places a CSV file into a temporary folder where it will remain until another script picks it up for import into my DB. This is a separated script and for various reasons cannot do both the placement into the temp folder AND the consecutive database import.
Since I now have a separated import script, I first need to scan the temp folder and look for the import-file, which is the ONLY file in the folder anyway, but has a constantly changing filename that I cannot pre-define. My question now is, how can I get the filename of said file, assign it to a variable and use this later for the database import?
When using a foreach() loop I end up with an array, but rather would like a string for further usage.
PHP
if(file_exists('./'.$temp)) {
$files = scandir('./'.$temp.'/');
foreach ($files as $attachment) {
if (in_array($attachment, array(".",".."))) continue;
$import_file = $attachment;
}
} else {
die("Temp Folder for $temp could not be found, hence no files exist for import. Operation cancelled.");
}
Since scandir is ordered alphabetically (http://php.net/manual/en/function.scandir.php), you file will always be at the end of the scandir array (on non-unix systems it is the only file, on unix systems it comes after . and ..).
Thus, you just need to get the last item of the array, like so:
$s = scandir("./".$temp."/");
$import_file = $s[count($s)-1];
This code automatically retrieves the name of the third file in the temp folder, so as long as there are no other files in there it should work perfectly.

Check for new files in a folder

I have a php script i run every 5 minutes with Cron from a folder. In the folder there is several images and i add more as time goes.
I was wondering how i can make the php script in the beginning check if NEW files exist after the last time the script was run? If new files exist the script should just go on and if no new files exist then it should not go on. I tried searching around but i cant find anything regarding php.
Anyone that know a quick solution to this problem maybet ?
If the new files are also created with a new timestamp, you can use filemtime() to fetch only files that were created/modified in a specified window of time.
Example:
$files = glob("folder/*.jpg");
$files = array_filter($files, function ($file) { return filemtime($file) >= time() - 5*60; /* modified in the last 5 minutes */ });
if ($files)
{
// there are new files! $files is an array with their names
}
To make sure you won't miss any file, you might want to store the time from last run somewhere, so in case cron delays a second or two and new files were created precisely within that window, you won't lose track of them.
Update for comments:
Now, to store the time from last check, thats up to you to decide how you will do that, you can use database, file, some sort of environment variable etc., but here is an example of how you can do something really simple storing time() in a file:
$last = (int)file_get_contents('folder/timestamp.txt');
file_put_contents('folder/timestamp.txt', time());
$files = glob("folder/*.jpg");
$files = array_filter($files, function ($file) { return filemtime($file) > $last; });
if ($files)
{
// there are new files! $files is an array with their names
}
Just make sure your PHP script can modify folder/timestamp.txt and with this script it will always process new files modified since the last run, no matter how long ago it happened.
Method :
store current time whenever the cron executed in a file or database.
every time when cron starts get the last executed time of the cron from your file or database
count the file which creates after last execution time.
if count greater than 0. process the cron. other wise stop.
You could keep track of the time the script was last run and use filemtime to check if the file was updated or created after your last execution.
http://php.net/manual/en/function.filemtime.php
int filemtime ( string $filename )
Use filemtime() as follows,You will get the added time as date format.
$file_time = date ("F d Y H:i:s.", filemtime($filename);

php move/copy image files to new directory/folder structure in linux

I have a php/mysql website where users create listings and upload multiple images (3 image sizes for each). I made the mistake of storing the images in folders as below :
images/listings/listing_id/image-name.jpg
images/listings/listing_id/thumbs/image-name.jpg
images/listings/listing_id/large/image-name.jpg
Unfortuantely now I have come across the problem where the maximum number of sub directories is 30,000 and my code breaks.
I want to now change my folder structure to the one below :
images/listings/yyyy/mm/dd/listing_id/image-name.jpg
images/listings/yyyy/mm/dd/listing_id/thumbs/image-name.jpg
images/listings/yyyy/mm/dd/listing_id/large/image-name.jpg
I decided the best way forward would be to create a php script to loop around all directories in the 'images/listings/' folder, and copy every image in to a new directory as specified above. or each 'listing_id' folder, I would need to lookup using mysql the listing_id, and get the created_date and then split the date to get the yyyy mm dd.
I'm totally lost in creating the php script, would it be possible to rename the existing directory structure without copying and deleting the old images, or would I need to copy the old images, create the new directories, move them and then delete the old folders?
So long as you don't have any listing_ids that are the same as a 4-digit year you should be able to create the new folder structure alongside the existing one.
You seem to already have a plan for how to do it, you should try actually writing some code.
Hint: rename() is the same as 'move'. Don't do "copy and delete" unless you want it to take 10x longer.
Lastly, as a rule of thumb you should try to avoid having any folder with more than about 1000 entries if possible. If there are a lot of filesystem operations that have to use the directory index for a folder that large it can drastically reduce filesystem performance.
You can use
$origin = "images/listings";
$final = "images/final";
$start = strlen($origin) + 1;
$di = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($origin, RecursiveDirectoryIterator::SKIP_DOTS));
foreach ( $di as $file ) {
if ($file->isFile()) {
$mtime = $file->getMTime();
$date = sprintf("%d/%d/%d", date("Y", $mtime), date("m", $mtime), date("d", $mtime));
$new = sprintf("%s/%s/%s", $final, $date, substr($file, $start));
$dir = dirname($new);
is_dir($dir) or mkdir($dir, null, true);
rename($file, $new);
}
}
For the moving of image,you can use the rename() Function of php.
For example
rename("../app/temp/natural.jpeg","../public/public_photo/natural.jpeg");
Above given code natural.jpeg from the folder /aap/temp/ has moved to the folder /public/public_photo/

Rename causing file access time to change

I am trying to move a file between directories on the same filesystem. The difficulty I am having is that when I use rename() the file access time is changed for that file on the filesystem.
I tried using shell_exec() with mv, though for some reason when I call mv in this way it copies the file and then deletes the original which takes much longer.
Is there any way to move the file quickly without changing the access time? Or can I change it back after calling rename()?
As a general rule the access time from a file must be changed when a function like rename(), or any other function that access a file, do it.
As for changing the access time of a file. This is only possible using the touch function, like described in the manual:
bool touch ( string $filename [, int $time = time() [, int $atime ]] )
Attempts to set the access and modification times of the file named in the filename parameter to the value given in time. Note that the access time is always modified, regardless of the number of parameters.
As you can see the time parameter is described in the manual as:
touch time
If time is not supplied, the current system time is used.
And here is an example from the same page of setting the access time one hour back from a file:
<?php
// This is the touch time, we'll set it to one hour in the past.
$time = time() - 3600;
// Touch the file
if (!touch('some_file.txt', $time)) {
echo 'Whoops, something went wrong...';
} else {
echo 'Touched file with success';
}
?>
However, be aware that the touch function, as described, attempts to change the file. If you have no permission for example the function will return false. (and won't change the file time)
Cheers
You can temporarily store the access time of the file using fileatime and modify it using touch.
$filename = 'somefile.txt';
$original_timestamp = fileatime($filename);
// .. modify file here ..
touch($filename, $original_timestamp);

Select a file that was created the last minute

Do you know if there is a function in php where it can find all the files in a given directory, that were created the last 1 minute (or in any case at a specified time?).
For example, to select all the txt files that were created the last 10 minutes in a directory..
I hope it's clear what I mean!
Thanx
D.
There is no creation time as such, only modified-time, which will work reliably across operating systems.
The filectime() and filemtime() filesystem functions in PHP will allow
you to check and see when a file has last been changed.
It will return
a timestamp holding the value of the time the file was last altered
You could iterate through the files in the folder, while checking filemtime().
Something like,
foreach (glob("*.txt") as $filename) {
echo filemtime($filename); //echoes timestamp
}
Get all files in directory, loop them through and apply filetime() function to see when they were created/modified. Copy them to another array and do with them what you please.
You can try
$it = new GlobIterator(__DIR__ . "/*.txt");
$last10mis = 600;
$list = array();
foreach ( $it as $file )
(time() - $file->getMTime()) <= $last10mis and $list[] = strval($file);
var_dump($list); // all txt files modified in the last 10mins
There is a function in PHP called filemtime that will return the modified time in a UNIX timestamp.
http://php.net/manual/en/function.filemtime.php
from there, and in the example ont that page, it should be fairly straightforward to apply to your needs.

Categories