Skip to Content
Course content

99: Directory Traversal Functions: scandir, glob

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Think of your server's file system like a physical filing cabinet. If I tell you to "scan the drawer," you're going to open it and read every single label you see—including the folder dividers, the empty envelopes, and the random scraps of paper. You're just listing everything that exists in that space. That is exactly what scandir() does.

Now, if I say, "Go find me every blue folder that starts with the word 'Invoice' and ends with a '.pdf' label," you aren't reading everything. You're filtering as you look, ignoring anything that doesn't match your specific criteria. That's how glob() works.

Getting the Full Picture with scandir

When you need to know exactly what is inside a directory, scandir() is your tool. It returns an array of all files and directories found. However, there is a quirk I want you to watch out for: it always includes the current directory (.) and the parent directory (..). If you're looping through files to process them, these two will usually crash your script if you try to treat them like actual files.

$files = scandir('uploads/user_documents');

foreach ($files as $file) {
    // I always filter out the dot-directories first
    if ($file === '.' || $file === '..') {
        continue;
    }
    echo "Found file: $file 
"; }

It's a blunt instrument. It doesn't care about extensions or naming conventions; it just gives you the raw list.

Targeted Hunting with glob

In my experience, you'll actually find yourself using glob() more often. Why? Because we rarely need everything. Usually, we need "all the JPEGs" or "all the CSVs from last month." glob() uses pattern matching (wildcards), which makes it incredibly powerful for specific tasks.

The asterisk (*) is the most common wildcard, representing "anything." Here is how I'd use it to grab only the PDF reports from a directory:

// This only returns files ending in .pdf
$pdfs = glob('reports/*.pdf');

foreach ($pdfs as $pdf) {
    // Note: glob returns the full path (e.g., 'reports/annual_2023.pdf'), 
    // unlike scandir which only returns the filename.
    echo "Processing report: " . basename($pdf) . "
"; }

If you need to be even more specific, you can use brackets. For example, glob('logs/[0-9]*.log') would find any log file that starts with a number. It saves you from having to pull a massive array via scandir() and then writing a bunch of if (str_ends_with(...)) logic to filter the results yourself.

Choosing the Right Tool for the Job

I've seen developers use scandir() and then manually filter the results using preg_match(). While that works, it's a lot of extra code. If you can describe what you're looking for with a pattern, use glob(). It's cleaner and more intentional.

Use scandir() only when the directory is small and you truly need an exhaustive list of every single item, regardless of its type or name. Just remember to handle those pesky dot-directories, or you'll be debugging "Permission Denied" errors for an hour.




📋 Practical Task

The Automated Log Archive Tool

Imagine you have a folder named /logs that gets filled with files like error_2023-01-01.log, access_2023-01-01.log, and some random readme.txt files. You need to build a script that archives these logs.

Your task: Write a PHP script that:

  • Uses glob() to find all files in the logs/ directory that end with the .log extension.
  • Loops through those specific files.
  • For each log file found, prints a message saying: "Archiving [filename]...".
  • Ensure that non-log files (like .txt or .md) are completely ignored by the script.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.