Scan a directory of images with PHP and Increment a counter for duplicate filename matches

StackOverflow https://stackoverflow.com/questions/23482780

  •  16-07-2023
  •  | 
  •  

سؤال

I have an upload folder that has images inside of it that are named in this format...

10000XXXX-COUNT-DATE-EMPLOYEE-PP-FILEEXTENSION

which looks like this...

100002246-1-2014-05-05-David.Rosales-PP.jpg

Each time a photo is uploaded using PHP I need to scan the files in this directory and find a match for the ID part which is the first 9 digits of the filename.

IF a match is found, I then need to append a number to the COUNT position which is in the number 11 character spot from the left.

The idea is an ID can have 5-6 images. If the ID has 1 image already then the next image should be named 100002246-2-2014-05-05-David.Rosales-PP.jpg and after that another image on a different upload sessions would be 100002246-3-2014-05-05-David.Rosales-PP.jpg so each new image for an ID number will increment by 1 number. You can see I have added the count number at the number 11 character spot.

I am not sure how to best achieve this right now. I cannot use a database so I have to do this during the upload process and scan the directory to find any matches for an image.

Any ideas and example of how I can best do this please?

Something like this for scanning the directory looks promising...

foreach (new DirectoryIterator('.') as $item) {
    echo $item, PHP_EOL;
}

UPDATE - My attempt at a solution so far

<?php
$orderId = $_GET['orderid'];


$dir = new DirectoryIterator('uploads');
$fileMatches = array();

foreach ($dir as $fileinfo) {

    $filenameId= substr($fileinfo->getFilename(), 0, 9);

    if($filenameId === $orderId){
        //store File ID matches in an array
        $fileMatches[] = $filenameId;
    }
    echo $fileinfo->getFilename() . "<br>";
}
$totalImages = count($fileMatches);
echo '<hr>Total Images found for this ID '.$orderId.' = '.$totalImages;
echo '<hr>New count for image would be = '. ($totalImages+1);

?>
هل كانت مفيدة؟

المحلول

You might be able to use glob() for your purposes. Supposing all pictures are in a directory named imgs:

$user_imgs = count(glob('imgs/*'.$user_id.'*')));

$user_imgs will contain the number of files in imgs that have $user_id in the file name.

You can get more creative with the pattern, if need be. This example just finds all files that have $user_id anywhere in the file name. Up to you how specific you want to be regarding the pattern you are searching for.

UPDATE based on your attempted solution

You can simplify your algorithm to this:

$orderId = $_GET['orderid'];

$all_images = glob('uploads/'.$orderId.'*');

foreach($all_images as $i)
    echo $i . '<br/>';

$totalImages = count($all_images);

echo '<hr>Total Images found for this ID '.$orderId.' = '.$totalImages;
echo '<hr>New count for image would be = '. ($totalImages+1);

UPDATE in consideration of new requirements

$orderId = $_GET['orderid'];

$all_images = glob('uploads/'.$orderId.'*');

$pp = $qc = 0;

foreach($all_images as $i) {
    if (strpos($i, '-PP.')!==false)
        $pp++;
    elseif (strpos($i, '-QC.')!==false)
        $qc++;
}

echo '<hr>Total Images found for this ID '.$orderId.' (PP) = '.$pp;
echo '<hr>New count for image would be = '. ($pp+1);

echo '<hr>Total Images found for this ID '.$orderId.' (QC) = '.$qc;
echo '<hr>New count for image would be = '. ($qc+1);

نصائح أخرى

To split the string up into logical pieces, you can split and then join it later, once you have manipulated it. Here is something that I've just tested on my machine, and it works.

<?php 
// note explicitly set here, but in wild it might be int
$_GET['orderid'] = '100002246';

if(! isset($_GET['orderid']) || ( isset($_GET['orderid']) && !is_string($_GET['orderid'])) 
  || (isset($_GET['orderid']) && is_string($_GET['orderid']) && !preg_match('/^[0-9]+$/', $_GET['orderid']))) {
    // don't run script, this isn't a valid ID
    die("We didn't have a good name\n");
  }

foreach (new DirectoryIterator('.') as $fileInfo) 
{
    if($fileInfo->isDot()) continue;

    $parts = preg_split('/-/', $fileInfo->getFilename());

    if(count($parts) != 7) 
    {
        echo "Cannot parse this file: ", $fileInfo->getFilename(), PHP_EOL;
        continue;
    }

    $associated_parts = array(
        "id"    => (int)$parts[0],
        "count" => (int)$parts[1],
        "date"  => $parts[2] . '-' . $parts[3] . '-' . $parts[4],
        "name"  => $parts[5],
        "ext"   => $parts[6]
    );

    if($associated_parts['id'] == $id) 
    {
        $associated_parts['count'] = $associated_parts['count'] + 1;
        $new_file = implode('-', $associated_parts);
        rename($fileInfo->getFilename(), $new_file);        
    }
}

foreach (new DirectoryIterator('.') as $fileInfo) 
{
    if($fileInfo->isDot()) continue;
    echo $fileInfo->getFileName(), PHP_EOL;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top