Get latest file trailing number in php - php

I have something like this in my directory:
slider-1.jpg
slider-2.png
slider-4.gif
slider-8.png
slider-11.gif
Now is there a way to get the last trailing number of "slider" images ?
I need to get this so the next uploaded image should be named slider-12.xxx
I tried for each loop, but it obviously gets me slider-3 as a next name which is false in my case :)
ok, here is how I did it
foreach ($files as $filename) {
$filesarr[]= $filename;
$namearr = explode('.', $filename); //I had to grab this piece as well during the project, so this is main reason not usin Louis proposal.... i needed that array for something else...
$numbers = explode('-', $namearr[1]);
$compare[]=$numbers[2];
}
sort($compare, SORT_NUMERIC);
$assigned_number = end($compare) + 1;

You could try something like this:
$max = 0;
foreach($files AS $file) {
$max = max($max, filter_var($file, FILTER_SANITIZE_NUMBER_INT));
}
$max++;
or this:
natcasesort($files);
$max = filter_var(array_slice($files, -1), FILTER_SANITIZE_NUMBER_INT) + 1;

Related

Need php to load files from folders and subfolders, and then sort the results added to a array

I need to search into folders and subfolders in search for files. In this search I need to know the files names and their path, because I have different folders and files inside of those.
I have this name 05-Navy, and inside this folder I have 3 files called 05_Navy_White_BaseColor.jpg, 05_Navy_White_Normal.jpg and 05_Navy_White_OcclusionRoughnessMetallic.jpg.
I need to only get one of them at a time because I need to add they separately to different lists.
Then I came up with the code below:
function getDirContents($dir, &$results = array()) {
$files = scandir($dir);
$findme = '_BaseColor';
$mypathCordas = null;
$findmeCordas = 'Cordas';
foreach ($files as $key => $value) {
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
$mypathCordas = $path;
$pos = strpos($mypathCordas, $findme);
$posCordas = strpos($mypathCordas, $findmeCordas);
if (!is_dir($path)) {
if($posCordas == true){
if($pos == true){
$results[] = $path;
}
}
}
else if ($value != "." && $value != ".." ) {
if($posCordas == true){
echo "</br>";
getDirContents($path, $results);
//$results[] = $path;
}
}
}
sort( $results );
for($i = 0; $i < count($results); $i++){
echo $results[$i];
echo "</br>";
}
return $results;
}
getDirContents('scenes/Texturas');
as output result I get this: Results1
Which is not ideal at all, the biggest problem is that the list inserts the same values every time it has do add new ones, and as you can see, it doesn't sort one bit, but it shuffles. I did other things, like I have tried to use DirectoryIterator which worked really well, but I couldn't sort at all...
The printing each time something new is on the list might be my for(), but I am relatively new to php, so I can't be sure.
Also, there's this thing where it gets all the path, and I already tried using other methods but got only errors, where I would only need the scenes/texturas/ instead of the absolute path....

PHP display random n images from directory

I want to display random n number of images from a folder. Currently i am using this script to display images
<?php
$dir = './images/gallery/';
foreach(glob($dir.'*.jpg') as $file) { ?>
<div class="item"><img src="<?php=$file;?>"></div>
<?php } ?>
I want only 10 (or n number) images, that too randomly. How to do this?
The shuffle() method will put the elements of a given array in a random order:
<?php
$dir = './images/gallery/';
function displayImgs($dir, $n=10){
$files = glob($dir.'*.jpg');
shuffle($files);
$files = array_slice($files, 0, $n);
foreach($files as $file) { ?>
<div class="item"><img src="<?php=$file;?>"></div>
<?php }
} ?>
Usage:
displayImgs("/dir/temp/path", 20);
Well, this might be overkill, but you can also use a directory iterator and some randomness to achieve this. I used a modified version of the random numbers generation function from this answer.
make sure that the path you give to the function is relative to the directory in which the script resides, with a slash at the beginning. The __DIR__ constants will not change would you happen to call this script from different places in your file hierarchy.
<?php
function randomImages($path,$n) {
$dir = new DirectoryIterator(__DIR__. $path);
// we need to know how many images we can range on
// but we do not want the two special files . and ..
$count = iterator_count($dir) - 2;
// slightly modified function to create an array containing n random position
// within our range
$positionsArray = UniqueRandomNumbersWithinRange(0,$count-1,$n);
$i = 0;
foreach ($dir as $file) {
// those super files seldom make good images
if ($file->getFilename() === '.' || $file->getFilename() === '..') continue;
if (isset($positionsArray[$i])) echo '<div class="item"><img src="'.$file->getPathname().'"></div>';
$i++;
// change the count after the check of the filename,
// because otherwise you might overflow
}
}
function UniqueRandomNumbersWithinRange($min, $max, $quantity) {
$numbers = range($min, $max);
shuffle($numbers);
return array_flip(array_slice($numbers, 0, $quantity));
}
Let us first create a array and push some random numbers into it. And as per you let $n be 10.
$n = 10;
$arr = array();
for($i = 1; $i <= $n; $i++){
/* Where $n is the limit */
$rand = rand($n);
array_push($arr, $rand);
}
So now we have an array containing the random digits and now we have to echo out the images by iterating over the array:
foreach($arr as $image){
$intToStr = (string) $image;
foreach(glob($dir. $intToStr . '.jpg') as $file){
echo "<div class='item'>$file</div>";
}
}
This would echo out your images.

Sort array by date before pagination after readdir

I have code to display images from a folder with pagination. I need to alter it so that it displays the newest image first on page one, and the oldest on the last page. I have tried a few methods but nothing seems to work. Please help!
$mydir = opendir($maindir) ;
$limit = 78;
$offset = ((int)$_GET['offset']) ? $_GET['offset'] : 0;
$files = array();
$page='';
$exclude = array( ".", "..", "index.php",".htaccess","guarantee.gif") ;
while($fn = readdir($mydir))
{
if (!in_array($fn, $exclude))
{
$files[] = $fn;;
}
}
closedir($mydir);
sort($files);
$newICounter = (($offset + $limit) <= sizeof($files)) ? ($offset + $limit) : sizeof($files);
for($i=$offset;$i<$newICounter;$i++) {
//SHOW THE IMAGES HERE
};
You can order the files by its file modification time:
<?php
$mydir = opendir($maindir) ;
$limit = 78;
$offset = ((int)$_GET['offset']) ? $_GET['offset'] : 0;
$files = array();
$page='';
$exclude = array( ".", "..", "index.php",".htaccess","guarantee.gif") ;
while(false !== ($img_file = readdir($mydir))){
if (!in_array($img_file, $exclude)){
# <<<<<<<<<<<<<< CHANGE 1 <<<<<<<<<<<<<<<<
//Put the creation date as the array's key:
$files[date('Y m d, H:i:s',filemtime($img_file))] = $img_file;
}
}
closedir($mydir);
# <<<<<<<<<<<<<< CHANGE 2 <<<<<<<<<<<<<<<<
//order files by date in ascending order:
ksort($files);
//reverse the array (you need the newest files first)
$files = array_reverse($files, false);
/*NOTE: in this point you have your images in $files array which are ordered by the file modification time of each file, so you only need the code to display them. I don't know how are you displaying your images, but that is the easiest part of the problem.*/
foreach($files as $a_image){
echo "<img href='" . $maindir . $a_image ."' alt='Image not found' width='100%' height='auto'/>";
}
?>
It's difficult get the exact creation time of a file in all platforms. So I recommend to you that concatenate the current date with the file name when you create the file.

how to sort file names having string plus date plus number

I wrote a script to get all the files from a given directory and upload those files to my site. However, I am facing a problem - when I print my filenames of the directory those are coming as follows.
Products010420141400170007.xml
Products010420141402380008.xml
Products010420141406240009.xml
Products100320141739560000.xml
Products180320142116150001.xml
Products180320142121210002.xml
Products210320141150070003.xml
Products240320141643400004.xml
Products310320141848450005.xml
But I need them to sort on the basis of date and the last numbers. Filename format is
"Productsddmmyyhis0001.xml"
Products100320141739560000.xml
Products180320142116150001.xml
Products180320142121210002.xml
Products210320141150070003.xml
Products240320141643400004.xml
Products310320141848450005.xml
Products010420141400170007.xml
Products010420141402380008.xml
Products010420141406240009.xml
How can I achieve this?
Thanks for your answer guys.
I solved it like this. Can you tell me is it fine for future, currently it is working fine.
$files = ftp_nlist($conn_id, ".");
foreach($files as $file)
{
$length = strlen($file);
$key = substr($file,22,($length-22));
$final_array[$key] = $file;
}
ksort($final_array);
While parsing can be done with regex, in your case it's better with substr()
$files = [
'Products010420141400170007.xml',
'Products010420141402380008.xml',
'Products010420141406240009.xml',
'Products100320141739560000.xml',
'Products180320142116150001.xml',
'Products180320142121210002.xml',
'Products210320141150070003.xml',
'Products240320141643400004.xml',
'Products310320141848450005.xml'
];
$f = function($z, $offset)
{
return strtotime(
sprintf(
'%s.%s.%s %s:%s:%s',
substr($z, $offset, 2),
substr($z, $offset+2, 2),
substr($z, $offset+6, 4),
substr($z, $offset+10, 2),
substr($z, $offset+12, 2),
substr($z, $offset+14, 2)
)
);
};
usort($files, function($x, $y) use ($f)
{
$dx = $f($x, 8);
$dy = $f($y, 8);
if($dx==$dy)
{
return substr($x, 22, 4)-substr($y, 22, 4);
}
return $dx-$dy;
});
-since substr() will work much faster. Note, that code above is bound to file name structure and will fail if there will be invalid entries.
It will parse file name with extracting date & time parts with offset and then, if corresponding timestamps are equal, compare numeric (4 digits) postfixes.
I have created the following function to sort files name:
Based on the requirement filename is in this format: Productsddmmyyhis100000000.xml
So the following function will sort filenames based on year, month, date and file number respectively.
// Main funcion to sort filenames
function sort_files($files)
{
$temp_array = array();
foreach ($files as $file)
{
$key = substr($file, 12, 4) . substr($file, 10, 2) . substr($file, 8, 2) . substr($file, 16);
$temp_array[$key] = $file;
}
ksort($temp_array);
return $temp_array;
}
$files = array(
"Products010420141400170007.xml",
"Products010420141402380008.xml",
"Products010420141406240009.xml",
"Products100320141739560000.xml",
"Products180320142116150001.xml",
"Products180320142121210002.xml",
"Products210320141150070003.xml",
"Products240320141643400004.xml",
"Products310320141848450005.xml"
);
$sorted_files = sort_files($files);
echo "<pre>" . print_r($sorted_files, TRUE) . "</pre>";
If the file format is : "Products{ddmmyyyyhhmmss}XXXX.xml"
You should try :
$all = [...]; // array of string with every files names;
$files = array();
foreach($all as $name) {
$year= substr($name,12,4);
$month = substr($name,10,2);
$day = substr($name,8,2);
$hour = substr($name,16,2);
$min = substr($name,18,2);
$sec = substr($name,20,2);
$key = mktime($hour,$min,$sec,$month,$day,$year);
// you got your timestamp
$files[$key] = $name;
}
foreach($files as $name) {
echo $name;
}
It should display your files from the oldest to the most recent.
But you've got a kind of sorted array. If you want classical keys :
// instead of the last foreach :
$all = array();
foreach($files as $name) {
$all[] = $name;
}
// for reversed array : (recent first)
array_reverse($all);

PHP - search and replace then sort and echo

I've managed (well, stackoverflow has shown me how) to search a directory on my server and echo and image. The trouble is the images in the folder are named by an IP camera yy_mm_dd_hh_mm where dd (and other date digits) have either one or two digits. I need them to have a preceeding zero so that I don't end up with, for example, an image taken at 9:50am being treated as a higher value than the photo taken more recently, at 10:05am. (I want it to treat it as 09_50 and 10_05 to fix the issue).
I've looked at search and replace but cannot get this to work within my current code:
function webcam_image () {
foreach (glob( "../camera/IPC_IPCamera*.jpg") as $f ) {
$list[] = $f;
}
sort($list);
echo array_pop($list);
}
example file = IPC_IPCamera_13_7_24_9_57_45.jpg
any help would be much appreciated!
Thanks
Ali
I would ignore the file name altogether and use a DirectoryIterator, fetching the files actual modified date. Something like this might work.
$files = array();
$iterator = new \DirectoryIterator('/path/to/dir');
foreach ($iterator as $file) {
if(! $file->isDot()) $files[$file->getMTime()] = $file->getFilename();
}
ksort($files);
print_r($files);
Take a look here for more information: http://php.net/manual/en/class.directoryiterator.php
If I have understood you correctly, you could handle this by preg_replaceing the files.
So you could loop through your files and do the following
$newFilename = preg_replace('/_([0-9])_/', '_0$1_', $oldFilename);
rename($oldFilename, $newFilename);
You can try something like:
function webcam_image () {
foreach (glob( "../camera/IPC_IPCamera*.jpg") as $f ) {
$digits = explode('_', substr(substr($f, 13), 0, -4));
foreach($digits as &$digit){
$digit = sprintf("%02d", $digit);
}
unset($digit);
$list[] = 'IPC_IPCamera_' . implode('_', $digits) . '.jpg';
}
sort($list);
echo array_pop($list);
}
You can use sprintf()
$list[] = $f;
with the following
$list[] = sprintf("%02s", $f);

Categories