Advertisement
PHP

Quick Tip: Loop Through Folders with PHP's Glob()

by

Are you still using opendir() to loop through folders in PHP? Doesn't that require a lot of repetitive code everytime you want to search a folder? Luckily, PHP's glob() is a much smarter solution.


Introduction

Here's an example of echoing out some information from a folder, using the traditional opendir() function.


	$dir = "/etc/php5/";

	// Open a known directory, and proceed to read its contents
	if (is_dir($dir)) 
	{
		
		if ($dh = opendir($dir)) 
		{
			
			while (($file = readdir($dh)) !== false) 
			{
				echo "filename: $file : filetype: " . filetype($dir . $file) . "\n";
			}
	
			closedir($dh);
	
		}
	
	}

That should look somewhat familiar. We can massively shorten the code above with:

	$dir = "/etc/php5/*";

	// Open a known directory, and proceed to read its contents
	foreach(glob($dir) as $file) 
	{
		echo "filename: $file : filetype: " . filetype($file) . "<br />";
	}

Isn't that much easier? Eager to learn how the method works? If yes, then let's get on with it.

glob() supports a total of two arguments, with the second argument being optional. The first argument is the path to the folder, however, it's a bit more powerful than that.


Step 1. The First Argument

This first argument supports a pattern. This means that you can limit the search to specific filetypes or even multiple directories at the same time by using multiple asterixes "*". Let's assume that you have a website that allows users to upload images (just because I read this). Each user has his/her own folder within the folder "userImages." Inside these folder are two additional folders, called "HD" and "TN," for high definition (full-sized) images, and for thumbnails. Let's imagine that you want to loop through all your users' "TN" folders and print the filenames. This would require a relatively large snippet of code if you were to use open_dir(); however, with glob(), it's easy.

	foreach(glob('userImages/*/TN/*') as $image) 
	{	
		echo "Filename: " . $image . "<br />";	
	}

This will search userImages/any/TN/any and will return a list of the files that match the pattern.

	Filename: userImages/username1/TN/test.jpg
	Filename: userImages/username1/TN/test3.jpg
	Filename: userImages/username1/TN/test5.png
	Filename: userImages/username2/TN/subfolder
	Filename: userImages/username2/TN/test2.jpg
	Filename: userImages/username2/TN/test4.gif
	Filename: userImages/username3/TN/styles.css

We can even take things a step further, and be more specific by including a file format in our foreach statement:

	foreach(glob('userImages/*/TN/*.jpg') as $image) 
	{	
		echo "Filename: " . $image . "<br />";	
	}

Now, this will only return Jpegs.

	Filename: userImages/username1/TN/test.jpg
	Filename: userImages/username1/TN/test3.jpg
	Filename: userImages/username2/TN/test2.jpg

It gets even better. What if, for instance, you require Jpegs, but also Gifs; nothing else? Or what if you want to print only folder names? This is where the second argument comes into play.


Step 2. The Second Argument

The second argument is, as mentioned previously, optional. It does, however, provide a very nice set of optional flags. These will allow you to change the way your glob() behaves.

  • GLOB_MARK: Adds a slash to each directory returned
  • GLOB_NOSORT: Return files as they appear in the directory (no sorting)
  • GLOB_NOCHECK: Return the search pattern if no files matching it were found
  • GLOB_NOESCAPE: Backslashes do not quote metacharacters
  • GLOB_BRACE: Expands {a,b,c} to match 'a', 'b', or 'c'
  • GLOB_ONLYDIR: Return only directory entries which match the pattern
  • GLOB_ERR: Stop on read errors (like unreadable directories), by default errors are ignored

As you see, the potential requirements that we noted at the end of Step 1 can easily be fixed with GLOB_BRACE:

	foreach(glob('userImages/*/TN/{*.jpg,*.gif}', GLOB_BRACE) as $image) 
	{
		echo "Filename: " . $image . "<br />";	
	}

which will return this:

	Filename: userImages/username1/TN/test.jpg
	Filename: userImages/username1/TN/test3.jpg
	Filename: userImages/username2/TN/test2.jpg
	Filename: userImages/username2/TN/test4.gif

If we wish to only print subfolder names, we could use GLOB_ONLYDIR:

	foreach(glob('userImages/*/TN/*', GLOB_ONLYDIR) as $image) 
	{
		echo "Filename: " . $image . "<br />";	
	}

which will print:

	Filename: userImages/username2/TN/subfolder

Conclusion and One More Example

This method has been available since PHP 4.3, however, it's not used very often, strangely. I didn't learn it until quite late myself. Now, I often use glob() when loading plugins into my framework:

	foreach(glob('includes/plugins/*.php') as $plugin)
	{
		include_once($plugin);	
	}

That's all; I hope you enjoyed this quick tip, and let me know if you have any questions!

Related Posts
  • Computer Skills
    App Training
    Alfred Workflows for Advanced UsersAlfred400
    Well, you made it to the advanced tutorial. Well done! Now for the real work. Alfred can be used to do some complicated things, including recursive programming! The concepts here are not easy and not for the inexperienced programmer.Read More…
  • Code
    Theme Development
    Custom Controls in the Theme CustomizerTheme customizer custom control 400
    In the last article, we explored the advanced controls available in the Theme Customizer, and how to implement them. We’re going to look at how to create our own custom control, allowing you to choose which Category of Posts are displayed on the home page. To get started, download version 0.6.0 of our Theme Customizer Example.Read More…
  • Code
    WordPress
    Mastering WordPress Meta Data: Understanding and Using ArraysMetadata
    In the first part of this series, we covered what WordPress meta data is, how it can be retrieved, and the various data types (such as objects or arrays) in which it can be returned. Now it's time to learn about the different types of arrays. When you write an array manually you know what its structure is an what the name of each index is. But when you are building arrays by querying a database, you are going to need to do some detective work to determine the structure of the data returned and the names of the indexes.Read More…
  • Code
    PHP
    Creating a Photo Tag Wall With Twilio Picture Messaging & PHPProcedural to oop php retina preview
    Twilio's recently announced Picture Messaging has vastly opened up what we can do with text messaging, now we can attach photos to our text messages and have them get used in different ways. In our case, we are going to build a Photo Tag Wall, which will contain photos linked to tags that will be displayed on a website.Read More…
  • Computer Skills
    App Training
    PopClip: Scripting ExtensionsPopclip400
    PopClip is a great utility program that, once you get used to it, is very hard to live without. This tutorial is going to show how to write a scripting extension by making an example extension.Read More…
  • Code
    Creative Coding
    A Look at the WordPress HTTP API: A Practical Example of wp_remote_postDiagram http api
    In the previous article, we reviewed the previous articles regarding GET requests, the native PHP facilities for making requests, and reviewed WordPress wp_remote_post API function along with the arguments that it offers. In this article, we're going to make use of wp_remote_post such that we're actually able to see it in action. Remember that this - like wp_remote_post - is part of the HTTP API of which there are other functions worth reviewing. But, for now, we're going to put wp_remote_post to work. Specifically, we're going to do the following: When the page loads, we're going to submit some information to a custom script The script will examine the information and return it to our page We'll then display the data on the page Sure, it's a bit of a contrived example but it will give us the experience of creating a separate PHP script that can be used for operations triggered by the use of wp_remote_post. Anyway, for the purposes of this example, we are going to use the PHP $_SERVER collection to log when the user has submitted their preference rather than require that they have logged in. Finally, the source code will be made available on GitHub and accessible at the end of this series in the following article. For now however, let's get started with working on the plugin.Read More…