On ZDNet: Why I Will never buy a Mac

Search and map directory trees with ease using the right PHP class

Tags: Scripting languages, Listing B, File_Find class, Contributor Melonfire, File_Find, directory tree, PHP

  • Save
  • Print
  • Recommend
  • 1

Takeaway: The PEAR File_Find class takes all the pain out of searching multi-level directory structures using PHP.

Most of the time, iterating through nested PHP structures requires you to write a recursive function that travels through the hierarchy in a sequential manner, examining each and every element in it. But recursive functions are complex, messy things and most developers (including myself) don't really enjoy working with them. That's why, when my last project needed to scan a directory hierarchy for a particular file (a typical recursive-function task), I didn't even consider rolling my own code. Instead, I headed straight for PEAR and its File_Find class, which takes all the pain out of searching multi-level directory structures.

The File_Find class is designed to let you do two things really well. First, it lets you scan a directory tree and turn it into a PHP structure -- a nested array -- that reflects the parent-child relationships of the original hierarchy. Second, it lets you search the directory tree for one or more files matching a pattern. This pattern can be either a simple string, or a complex Perl regular expression; File_Find can handle either format, and will return an array containing detailed file and path information for each match.

To get started, install the package manually, by downloading it and extracting its contents to your PEAR base directory, or by using the PEAR installer.

Next, create the following PHP script (Listing A) and save it under your Web server's document root:

Listing A


<?php
// include class
include("Find.php");

// initialize finder
$finder = new File_Find();

// read directory tree and print
$tree = $finder->mapTree("/tmp");
print_r($tree);
?>

Here, I've instantiated a new File_Find() object, and then called its mapTree() method with a directory path. This mapTree() method reads the named directory and produces a two-element "array map" of its hierarchical structure. The first element of this array lists all the sub-directories found under the target directory, while the second element lists all the files found. It's then possible to scan through these lists and use them within an application -- for example, to visually reconstruct the directory tree, or to filter out files and directories based on custom criteria.

Listing B is an example of the output of the script above:

Listing B


Array
(
    [0] => Array
        (
            [0] => /tmp
            [1] => /tmp/dummyA
            [2] => /tmp/dummyB
            [3] => /tmp/dummyA/dummyC
         )

    [1] => Array
        (
            [0] => /tmp/data.txt
            [1] => /tmp/dummyB/metoo.mp3
            [2] => /tmp/dummyB/track.dat
            [3] => /tmp/dummyA/dummyC/parrot.gif
        )
)

You can also do this another way, with the mapTreeMultiple() method, which recursively reads the named directory and produces a nested array replicating its tree structure. Listing C shows you an example.

Listing C


<?php
// include class
include("Find.php");

// initialize finder
$finder = new File_Find();

// print recursive directory tree
$tree = $finder->mapTreeMultiple("/tmp");
print_r($tree);
?>

And Listing D shows you what the output might look like:

Listing D


Array
(
    [0] => data.txt
    [dummyA] => Array
        (
            [dummyC] => Array
                (
                     [0] => parrot.gif
                )

        )

    [dummyB] => Array
        (
            [0] => metoo.mp3
            [1] => track.dat
        )
)

Tip: You can add an optional parameter to mapTreeMultiple() to restrict the number of levels it drills down to when performing the recursion.

With the glob() method you can search the named directory for files matching a specific Perl-compatible regular expression. Take a look at Listing E.

Listing E


<?php
// include class
include("Find.php");

// initialize finder
$finder = new File_Find();

// search for matching files in named directory
$results = $finder->glob("/mp3/i", "/usr/local/stuff", "perl");
print_r($results);
?>

Here, the glob() method looks in the named directory for all files with the string mp3 within their names. Note my use of the i modifier, which makes the search case-insensitive, and my use of a third argument, which tells the class to use Perl regex functions instead of the default PHP functions.

The File_Find class really comes into its own with the search() method, which combines the power of the mapTreeMultiple() and glob() methods to perform multi-level directory search. Here's an example in Listing F.

Listing F


<?php
// include class
include("Find.php");

// initialize finder
$finder = new File_Find();

// search for matching files
// in named directory and subdirectories
$results = $finder->search("/exe/i", "/usr/local/winstuff", "perl");
print_r($results);
?>

And Listing G shows you a sample of the output:

Listing G


Array
(
    [0] => /usr/local/winstuff/4HELP.EXE
    [1] => /usr/local/winstuff/ARJ.EXE
    [2] => /usr/local/winstuff/bzip2.exe
    [3] => /usr/local/winstuff/CRLF.EXE
    [4] => /usr/local/winstuff/DECODE.EXE
    [5] => /usr/local/winstuff/GREP.EXE
    [6] => /usr/local/winstuff/GPG/gpg.exe
    [7] => /usr/local/winstuff/GPG/uninst-gnupg.exe
    [8] => /usr/local/winstuff/GPG/WinPT.exe
    [9] => /usr/local/winstuff/Fprot/F-PROT.EXE
)

And that's your recursive directory search, in just four lines of code!

As you can see, File_Find makes it possible to accomplish a relatively-complex task easily and efficiently, with minimal stress on your part, which is why I highly recommend it to you the next time you need to perform a file find operation on a directory tree. Try it out for yourself and happy coding!

  • Save
  • Print
  • Recommend
  • 1

Print/View all Posts Comments on this article

Are you prone to recursive functions? Mark W. KaelinTechrepublic Moderator | 06/22/06
Recursivity simplifies code a_chadili@... | 06/26/06

What do you think?

White Papers, Webcasts, and Downloads

Article Categories

Security
Security Solutions, IT Locksmith
Networking and Communications
E-mail Administration NetNote, Cisco Routers and Switches
CIO and IT Management
Project Management, CIO Issues, Strategies that Scale
Desktops, Laptops & OS
Windows 2000 Professional, Microsoft Word, Microsoft Excel, Microsoft Access, Windows XP,
Data Management
Oracle, SQL Server
Servers
Windows NT, Linux NetNote, Windows Server 2003
Career Development
Geek Trivia
Software/Web Development
Web Development Zone, Visual Basic, .NET

Smartphones

advertisement
Click Here