0

I have a value at $field

$field is a 5 digit number, and I have a folder full of images in image sets. So for each number e.g. "12345", there could be "12345_1" or "12345_2" etc. if multiple images exist.

I am using the following to check if each file exists, and then build a comma separated value for the files that do exist to insert into a CSV file.

For example, if A exists, and B exists, return "A,B"

I know what I am trying to achieve, and have the following...

if (file_exists('images/' . $field . '.JPG')) {
  $file1 = 'images/' . $field . '.JPG';
}

if (file_exists('images/' . $field . '_1.JPG')) {
  $file2 = 'images/' . $field . '_1.JPG';
}

if (file_exists('images/' . $field . '_2.JPG')) {
  $file3 = 'images/' . $field . '_2.JPG';
}

if((isset($file1)) && (!isset($file2)) && (!isset($file3))) {
  return "$file1";
} elseif((isset($file1)) && (isset($file2)) && (!isset($file3))) {
  return "$file1,$file2";
} elseif((isset($file1)) && (isset($file2)) && (isset($file3))) {
  return "$file1,$file2,$file3";
}

But this just seems like a really crap way of writing what I am trying to do, especially as in the real example, I am doing this for up to 10 files, so this is quite bulky.

Is there a better way to do this, or a method I am missing out on that could make life easier? (I'm still learning!)

3
  • 2
    Using an array and a loop would do a lot here. And you can already build your string using an if inside the first if statement. Commented Jun 27, 2016 at 13:13
  • Im struggling to figure out how to do a foreach if there is a number appended to each. There is also a max of ten files per image name, so I wouldn't want to crate an infinite check of whether 300 files exist etc. Commented Jun 27, 2016 at 13:19
  • You can use a simple for loop, then you already have your numbers. Commented Jun 27, 2016 at 13:21

5 Answers 5

2

EDIT

Old code probably didn't work as expected. Prepended ./ to images to find the right files. Now also using character ranges for case-insensitive file-extension search.

Why not glob? It looks for files based on a pattern you pass it and return an array with matched files.

$files = glob ('./images/' . $field . '*.[jJ][pP][gG]');

if (is_array($files) && count($files)) {
   // if you need to remove the `./` from the front of the file name,
   // use the following line
   $files = array_map(function($val) { return substr($val, 2); }, $files);
   return implode(',', $files);
}

It can search directories using a wildcard. See the first comment on documentation page for an explanation of how it works. Basically, * is a wildcard meaning match any character.

Sign up to request clarification or add additional context in comments.

Comments

0

It can all be done quite simply with a couple of loops like this

$field = '123456';

$max_loop = 10;
$files_to_check = [];
$result = '';

// generate filenames with _number added
// first the odd filename with no additional numeric
$files_to_check[] = "images/$field.jpg";
// loop all the others
for ( $x=1; $x <= max_loop; $x++) {
    $files_to_check[] = sprintf('images/%s_%d.jpg', $field, $x); 
}

foreach ( $files_to_check as $file ) {
    if (file_exists($file) ) {
        $result = $file . ',';
    }
}
$result = trim($result, ',');

return $result;

2 Comments

Thanks for you help, but I get a NOTICE Undefined variable: field_ on line number 13 with this. Can you put an underscore after a variable?
Ok, try that amendment using a sprintf instead of simple concatenation
0

SPL (StandardPHPLibrary) can also do the job. I read the directory first, then check for it's existence by isFile() method (also if it's a file) and finally store the matching filename to array.

$iterator = new DirectoryIterator(__DIR__);
foreach ($iterator as $fileinfo) {
    $isFile = $fileinfo->isFile();
    $isMatch = stripos($fileinfo->getFilename(), $field) !== false;
    if ($isFile && $isMatch) {
        $myFile[] = $fileinfo->getFilename()
    }
}

echo implode(",", $myFile);

Read more: DirectoryIterator PHP manual page

Comments

0

Try something like this. First in here you create a list of possible file endings (here up from _0.jpgup to_100.jpg). The first one is the original without_X.jpg`.

Then you loop over all and collect the existing files and finally implode them to get a comma sperated list.

$extensions = [".jpg",];
for ($i = 0; $i <= 100; $i++){
    $extensions[] = sprintf("_%d.jpg", $i);
}
$existing_files = [];
foreach ($extensions as $extension) {
    $filename = "images/" . $file . $extension;
    if(file_exists($filename)){
        $existing_files[] = $filename;
    }
}

$result = implode(",", $existing_files);

1 Comment

Of course not! Thanks for pointing out, I was writing to fast :)
0

If you are not calling function ,return is no need ! Assign one variable is better

$format = array(".JPG","_1.JPG","_2.JPG");
$file = array();
foreach ($format as $value) {
  if (file_exists('images/' . $field.$value)) {
  $file[] = 'images/'. $field.$value;
  }
}

$result = "";
$last = count($file)-1; //last index key
foreach ($file as $k=>$f) {
  if(isset($f)){
    ($last == $k) ? $result.= $f : $result.= $f.",";
  }
}
var_dump($result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.