Sorting Files into Folders - So STUCK!

Discussion in 'PHP' started by hav0k, Sep 18, 2007.

  1. #1
    I'm getting really stuck here...

    I have a list of files that I read from a folder:

    thumb.Aaliyah-1.jpg
    thumb.Aaliyah-22.jpg
    thumb.Aaliyah-3.jpg
    thumb.Abi-Titmuss-1.jpg
    thumb.Abi-Titmuss-2.jpg
    thumb.Abi-Titmuss-3.jpg
    thumb.Ada-Nicodemou-6.jpg
    thumb.Ada-Nicodemou-7.jpg
    thumb.Adele-Silva-3.jpg
    thumb.Adele-Silva-4.jpg
    thumb.Adriana-Karembeu-1.jpg
    Code (markup):
    I want to take the middle name, ex. Aaliyah or Ada-Nicodemou, and create a folder from that name. Then I want to move all related thumnails to that created folder. So far I was able to list the names only but if the names has 2 digits, ex Aaliyah-22, is outputs Aaliyah- since I'm using preset amount of characters to remove using the substr() function.

    So I was able to finally get the following list after trying many ways:

    Aaliyah
    Aaliyah-
    Aaliyah
    Abi-Titmuss
    Abi-Titmuss
    Abi-Titmuss
    Ada-Nicodemou
    Ada-Nicodemou
    Adele-Silva
    Adele-Silva
    Adriana-Karembeu
    Code (markup):
    You can see that "Aaliyah-" problem I mentioned earlier. So now I've come to a block and need some input about how to continue forward to reach my goal wrote about up above.

    Thanks!


    Here's the code I have so far:

    <?php
    
        $dir = 'C:\wamp\www\filesorter\thumbs';
        $dir_handle = @opendir($dir) or die("Unable to open $dir");
        $clist = array();
        while (false !== ($file = readdir($dir_handle)))
    	{
       		if($file!="." && $file!=".." && $file!="Thumbs.db" && $file!="Thumbs.")
              $clist[$file] = $file;
    	}
    	closedir($dir_handle);
    
        sort($clist);
    
        foreach ($clist as $key => $file1) {
            $rfile = str_replace("thumb.","",$file1);
            $refile = str_replace(".jpg","",$rfile);
            $dirname = substr("$refile", 0, -2);
            echo "$dirname<br />";
        }
    
    ?>
    PHP:

     
    hav0k, Sep 18, 2007 IP
  2. sea otter

    sea otter Peon

    Messages:
    250
    Likes Received:
    23
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Try this:

    
    <?php
    
    $dir = 'C:\wamp\www\filesorter\thumbs';
    
    $files = array();
    $pattern = '/^thumb\.(.*)\-[0-9]+\.jpg$/';
    
    $dh = @opendir($dir) or die('Could not open directory for reading.');
    while (($file = readdir($dh)) !== false) 
    	if (!is_dir($file) && $file !== 'Thumbs.' && $file !== 'Thumbs.db')
    	{
    		$matches=array();
    		preg_match($pattern, $file, $matches);
    		if ($matches[1] && !isset($files[$matches[1]]))
    			$files[$matches[1]]=$matches[1];
    	}
    @closedir($dh);
    
    foreach ($files as $dirname)
    	echo $dirname,'<br />';
    
    ?>
    
    PHP:
     
    sea otter, Sep 18, 2007 IP
  3. hav0k

    hav0k Active Member

    Messages:
    178
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    60
    #3
    Worked like a charm... could you explain a little bit what you changed though? I hate just being given code and not learning what it does. Thanks a bunch!
     
    hav0k, Sep 18, 2007 IP
  4. sea otter

    sea otter Peon

    Messages:
    250
    Likes Received:
    23
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Sure...

    Only a minor change on this line:

    
        if (!is_dir($file) && $file !== 'Thumbs.' && $file !== 'Thumbs.db')
    
    Code (markup):
    Which checks if the item read is a directory or one of the files to ignore. Rather than hardcode '.' and '..', this accommodates the (perhaps undesired) chance that there's a subdirectory in your thumbnail directory.

    In the while loop, I used the preg_match() pattern matching function to extract only the part of the filename you want.

    The pattern sent to preg_match is really where the action is:

    
    $pattern = '/^thumb\.(.*)\-[0-9]+\.jpg$/';
    
    Code (markup):
    This is a standard (PERL-compatible) regular expression. The '^' at the start means that the string we're matching starts with the characters that follow it (which in our case are the letters 'thumb.') Note that the '.' in 'thumb.' has an escape character before it.

    So we skip everything up until the name using this part of the pattern:

    
    ^thumb\.
    
    Code (markup):
    Next, we tell the pattern to match any character, which is what the (.*) phrase means. Because it's in parentheses, it will be saved into a variable for us to retrieve later.

    Now, if we stopped there, the pattern would match to the end of the string. But we don't want the tail end of it -- the part with '-11.jpg' or whatever. So we add a part to the pattern which ignores that:

    
    \-[0-9]+\.jpg$
    
    Code (markup):
    This means "match the dash character, followed by one or more number characters, followed by '.jpg'

    Notice in the call to preg_match that we send in the $matches() array. On return from the call, this will contain the results of our match, the part in (.*)

    However, the FIRST entry in the array is always the complete input variable, which is why you see me using $matches[1] everywhere instead of $matches[0].

    The next part of the while loop simply looks to see if the name is already in the array, and if not it adds it.


    90% of the work here is knowing how to use regular expressions :)
     
    sea otter, Sep 18, 2007 IP
    hav0k likes this.
  5. hav0k

    hav0k Active Member

    Messages:
    178
    Likes Received:
    4
    Best Answers:
    0
    Trophy Points:
    60
    #5
    Wow, that's awesome... I really appreciate it, thanks!
     
    hav0k, Sep 18, 2007 IP