PHP
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Object-Oriented PHP
-
Section 5: Working with Data
-
Section 6: Modern PHP (PHP 8)
-
Section 7: Working with Files and Networking
-
Section 8: Common PHP Frameworks Overview
-
Section 9: Tooling and Ecosystem
-
Section 10: Practical Projects
-
Section 11: Interview Practice
-
Section 12: More Standard Library
-
Section 13: Data Structures and Algorithms in PHP
-
Section 14: More Practice Exercises
-
Section 15: More Security and Best Practices
-
Section 16: More Testing and Tooling
-
Section 17: WordPress-Style CMS Concepts
-
Section 18: Advanced OOP Practice
-
Section 19: More Web Fundamentals
-
Section 20: Database Practice
-
Section 21: PHP Manual: Array Functions
-
Section 22: PHP Manual: Date and Calendar Functions
-
Section 23: PHP Manual: Filesystem and Directory Functions
-
Section 24: PHP Manual: Filter and Var Handling
-
Section 25: PHP Manual: Math Functions
-
Section 26: PHP Manual: JSON and XML
-
Section 27: PHP Manual: Network and Stream Functions
-
Section 28: PHP Manual: Error and Exception Handling
-
Section 29: PHP Manual: Output Control and Misc
-
Section 30: PHP Manual: FTP, Zip, and Mail
-
Section 31: Modern PHP Frameworks Deep Dive
-
Section 32: PHP Design Patterns
-
Section 33: More Practice Exercises
-
Section 34: PHP Performance and Deployment
-
Section 35: More Interview Practice
-
Section 36: More PHP Standard Library
-
Section 37: PHP Concurrency and Async
-
Section 38: More Web Development Practice
-
Section 39: PHP Testing Deep Dive
-
Section 40: Composer and Package Development
-
Section 41: PHP Security Deep Dive
-
Section 42: More Practical Projects
-
Section 43: Legacy PHP Maintenance
-
Section 44: More Algorithm Practice
-
Section 45: Final Practice and Review
-
Section 46: PHP for E-Commerce Patterns
-
Section 47: PHP API Design Deep Dive
-
Section 48: PHP Caching Strategies
-
Section 49: PHP Queue and Background Jobs
-
Section 50: PHP Multi-Tenancy Patterns
-
Section 51: PHP Real-Time Features
-
Section 52: PHP CMS and Content Modeling
-
Section 53: PHP Internationalization
-
Section 54: More Framework-Specific Practice
-
Section 55: PHP Legacy Code Refactoring
-
Section 56: More Practice Projects Round 2
-
Section 57: PHP Command-Line Applications
-
Section 58: PHP and Microservices
-
Section 59: More Interview and Review Round 2
99: Directory Traversal Functions: scandir, glob
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 thelogs/directory that end with the.logextension. - Loops through those specific files.
- For each log file found, prints a message saying: "Archiving [filename]...".
- Ensure that non-log files (like
.txtor.md) are completely ignored by the script.
There are no comments for now.