Download file from FTP while keeping the original "last change" date - php

I've build an FTP class in PHP with a function to download files from the FTP server.
This is the function so far
public function downloadData($serverFile, $localPath)
{
$fileName = basename($serverFile);
$file = $localPath.$fileName;
$download = false;
if(!file_exists($file))
{
// try to download $server_file and save to $local_file
if(ftp_get($this->connection_id, $file, $serverFile, FTP_BINARY)) {
$download = true;
}
}
return $download;
}
Basically it works fine, but when saving the data the "last change date" of the file is set to the current date/time. I somehow want to prevent this, because the original date is important for my needs.
Is there a way to keep the original modified date of the file?

It sounds like you believe there's something overwriting the timestamp. There's not. The timestamp is simply not transferred at all during an FTP download. So the local file has last modification time matching the transfer time (= the last time the local file was modified).
But you can of course explicitly set the timestamp after the download finishes.
Use ftp_mdtm to retrieve the timestamp of source file on FTP server.
Use touch to set the timestamp of target local file.
touch($file, ftp_mdtm($this->connection_id, $serverFile));

You cannot stop the system from updating the modified date when modifying a file. However, it depends drastically on why you need the creation date?
Unfortunately if you are running on Linux/Unix you cannot access the creation date information as only the last modified date is stored. However for Windows you can use filectime and it will return the creation time

Related

ftp listing and download file in current date

I have a case,
I have a remote server that contains so many generated transaction files (.txt) from 2015 until now. I must download it everyday real time. For now, i use PHP to download it all, but the method i think is not effectifely. First, I list all files, and then I read the component of the files such as the date modified, but this method is annoying. Make my program run slowly and take a very much time.
This is my code (I've used PHP Yii2),
public function actionDownloadfile(){
$contents=Yii::$app->ftpFs->listContents('/backup', ['timestamp','path','basename']); --> Much time needed while executing this line
var_dump($contents);
foreach ($contents as $value) {
if (date('Y-m-d',$value['timestamp']) == date('Y-m-d')){
echo "[".date('Y-m-d H:i:s')."] : Downloading file ".$value['basename']."\n";
$isi = Yii::$app->ftpFs->read($value['path']);
$dirOut = Yii::$app->params['out'];
$fileoutgoing = $dirOut."/".$value['basename'];
$file = fopen($fileoutgoing,"w");
fwrite($file,$isi);
}
}
}
i have a question,
Is that possible to list and download some files in ftp server just only on this current date without listing them all first?
Any solution either using PHP or Shell Script is OK.
Thank you so much (y)

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 Script for Monitoring Folder Creation

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

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);

Determining when smarty created a cache file

I've got a cms, each page stores the time that it was last updated in a database. I've got caching set up in smarty (3.1), but I want to be able to clear the cache and force it to create a new cache file if the page was updated since the last saved cache file, but to do that I need to know when the cached file was created.
Is there a way of getting the timestamp of the cached file?
Thanks
I have recently answered a similar question: Smarty cache site properties in database
<?php
// fill these if you do cache grouping and or have different compiles of the same template
$template = 'foobar.tpl';
$cache_id = null;
$compile_id = null;
$smarty = new Smarty();
$tpl = $smarty->createTemplate($template, $cache_id, $compile_id);
if ($tpl->isCached() && $tpl->cached->timestamp < $yourTimestampFromDB) {
$smarty->clearCache($template, $cache_id, $compile_id);
}
I'm not sure Smarty has anything internal for this. But look at filemtime() and filectime for determining when a file was last modified and changed respectively.
From php.net:
$filename = 'somefile.txt';
if (file_exists($filename)) {
echo "$filename was last changed: " . date("F d Y H:i:s.", filectime($filename));
}
Difference between modified-time and change-time:
Note: In most Unix filesystems, a file is considered changed when its inode data is changed; that is, when the permissions, owner, group, or other metadata from the inode is updated. See also filemtime() (which is what you want to use when you want to create "Last Modified" footers on web pages) and fileatime().

Categories