Thursday, March 3, 2011

Checking for file-extensions in PHP with Regular expressions

I'm reading all the files in a single directory and I want to filter on JPG,JPEG,GIF and PNG.

Both capital and small letters. Those are the only files to be accepted.

I am currently using this:

$testPics = takeFiles($picsDir, "([^\s]+(?=\.(jpg|JPG|jpeg|JPEG|png|PNG|gif|GIF))\.\2)");

and the function takeFiles looks like this:

function takerFiles($dir, $rex="") {
    $dir .= "/";
    $files = array();
    $dp = opendir($dir);
    while ($file = readdir($dp)) {
      if ($file == '.')  continue;
      if ($file == '..') continue;
      if (is_dir($file)) continue;
      if ($rex!="" && !preg_match($rex, $file)) continue;
      $files[] = $file;
    }
    closedir($dp);
    return $files;
  }

And it always returns nothing. So something must be wrong with my regex code.

From stackoverflow
  • I think something is wrong with your regex. Try testing regexes here first: http://www.spaweditor.com/scripts/regex/index.php

    I think this one might work for you:

    /^.*\.(jpg|jpeg|png|gif)$/i

    Note the /i at the end - this is the "case insensitive" flag, saves you having to type out all permutations :)

    Mark : you'll have to escape the dot.
    Phill Sacre : Thanks Mark, fixed. D'oh!
  • You should put slashes around your regexp. -> "/(...)/"

  • How about using glob() instead?

    $files = glob($dir . '*.{jpg,gif,png,jpeg}',GLOB_BRACE);
    
    R. Bemrose : As a side note, make sure $dir ends with a directory separator.
  • There are a few ways of doing this.

    Have you tried glob()?:

    $files = glob("{$picsDir}/*.{gif,jpeg,jpg,png}", GLOB_BRACE);
    

    Have you considered pathinfo()?:

    $info = pathinfo($file);
    switch(strtolower($info['extension'])) {
        case 'jpeg':
        case 'jpg':
        case 'gif':
        case 'png':
            $files[] = $file;
            break;
    }
    

    If you're insistant upon using the regular expression, there's no need to match the whole filename, just the extension. Use the $ token to match the end of the string, and use the i flag to denote case-insensitivity. Also, don't forget to use a delimiter in your expression, in my case "%":

    $rex = '%\.(gif|jpe?g|png)$%i';
    
  • Is there any reason you don't want to use scanDir and pathinfo?

    public function scanForFiles($path, array $exts)
    {
        $files = scanDir($path);
    $return = array();
    
    foreach($files as $file)
    {
      if($file != '.' && $file != '..')
      {
        if(in_array(pathinfo($file, PATHINFO_EXTENSION), $exts))) {
              $return[] = $file;   
            }
      }
    }
    
        return $return;
    }
    

    Sorry, not formatted so nicely. So you could also check if the file is a directory and do a recursive call to scan that directory. I wrote the code in haste so might not be 100% correct.

    e-satis : This answser should be at the top. Regexp are often overkill. I love them but you must stick to KISS when possible.
  • VERY useful stuff - thanks everyone.

  • Hi,

    I want to blacklist file extensions, i searched the internet but nothing works.

    I am looking for something like:

    /^.*\.(^exe|^rar|^pdf|^zip)$/i
    
    mynameiscoffey : drop all of the "^" except for the first one

0 comments:

Post a Comment