Reputation: 15442
My PHP's rusty and I'm hoping that someone can help me with a quick script - I don't really know where to start with it!
I have a folder containing zipped archives of various versions of a software product:
etc.
Now, on my web site I have a button to download the product. However, I'd like that button to always download the latest version.
It seems to me that a nice solution would be to link to a PHP script that would scan the folder for the latest version and deliver that file to the user as if they have pointed the browser directly at the file.
Can anyone provide me with a starting point?
Upvotes: 3
Views: 309
Reputation: 17361
I think it's the easiest to read the files from the directory into an array. Then natsort
the array and pop off the last entry.
Here is an example:
<?php
function getLatestVersion() {
$dir = dir('.');
$files = array();
while (($file = $dir->read()) !== false) {
$files[] = $file;
}
$dir->close();
natsort($files);
return array_pop($files);
}
Outputs
array(6) {
[0]=>
string(1) "."
[1]=>
string(2) ".."
[2]=>
string(16) "Product_1.00.zip"
[3]=>
string(16) "Product_1.05.zip"
[5]=>
string(16) "Product_2.00.zip"
[4]=>
string(17) "Product_10.00.zip"
}
EDIT
Like @j_mcnally pointed out in his comment below it's more efficient to let the webserver handle the serving of static files. Possible ways are direct links or redirecting the request from the PHP file to the right location using a 301
.
But if you still want to let PHP do the work. Here is an example.
Grabbed the example below from http://perishablepress.com/http-headers-file-downloads and altered it a bit.
<?php // HTTP Headers for ZIP File Downloads
// http://perishablepress.com/press/2010/11/17/http-headers-file-downloads/
// set example variables
// Only this line is altered
$filename = getLatestVersion();
$filepath = "/var/www/domain/httpdocs/download/path/";
// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath.$filename));
ob_end_flush();
@readfile($filepath.$filename);
?>
Upvotes: 2
Reputation: 13116
This code works by using the file modification time to determine the latest version in the given directory, perhaps using regular expressions on the file names would be a better approach, however this demonstraits PHP's DirectoryIterator.
$files = array();
foreach(new DirectoryIterator("productZips/") as $fileInfo) {
if(!$fileInfo->isFile()) continue;
$files[$fileInfo->getMTime()] = $fileInfo->getFilename();
}
ksort($files);
$latestFile = array_pop($files);
You can read more here: http://php.net/manual/en/class.directoryiterator.php
Upvotes: 0
Reputation: 4346
This should work. Of course, more checks can be added depending on what else can be stored in that folder; you may also change the way of reading the folder content if it contains too many files, etc.
Keyword in this code is probably strnatcmp()
for strings comparison.
<?php
$files = scandir('/path/to/files');
$result = array_reduce(
$files,
function($a, $b) {
$tpl = '/^Product_(.+).zip$/';
// return second file name if the first file doesn't follow pattern Product_XXX.zip
if (!preg_match($tpl, $a)) {
return $b;
}
// return first file name if the second file doesn't follow pattern Product_XXX.zip
if (!preg_match($tpl, $b)) {
return $a;
}
return strnatcmp($a, $b) >= 0 ? $a : $b;
},
''
);
Upvotes: 1
Reputation: 246
The below will look within the downloads
directory, find the latest file (by looking at the modify time of the files) and return the name of the newest file:
$dir = dir("downloads");
$files = array();
while (($file = $dir->read()) !== false) {
$files[filemtime($file)] = $file;
}
$dir->close();
ksort($files);
$fileToDownload = $files[0];
Hope this helps!
Upvotes: 0