<!DOCTYPE html>
<!-- ========================================== kroc camen of camen design ============================================= -->
<title>code · Sorting a Directory Listing Folders First, Then by File Type, Then by Name in PHP</title>
<link rel="stylesheet" type="text/css" href="/design/design.css" />
<meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=no" />
<link rel="alternate" type="application/rss+xml" href="/code/rss" title="Just code" />
<link rel="canonical" href="/code/php_directory_sorting" />
<!-- =================================================================================================================== -->
<header>
	<h1><a href="/" rel="index">
		Camen Design
	</a></h1>
	<nav><ul>
		<li><a href="/">all</a></li>
		<li><a href="/projects">projects</a></li>
		<li><a href="http://forum.camendesign.com">forum</a></li>
	</ul><ul>
		<li><a href="/quote/">quote</a></li>
		<li><a href="/writing/">writing</a></li>
		<li><a href="/blog/">blog</a></li>
		<li><a href="/photo/">photo</a></li>
		<li><a href="/code/" rel="tag">code</a></li>
		<li><a href="/art/">art</a></li>
		<li><a href="/link/">link</a></li>
		<li><a href="/poem/">poem</a></li>
		<li><a href="/audio/">audio</a></li>
	</ul><ul>
		<li><a href="/web-dev/">web-dev</a></li>
		<li><a href="/annoyances/">annoyances</a></li>
		<li><a href="/eve/">eve</a></li>
		<li><a href="/code-is-art/">code-is-art</a></li>
		<li><a href="/inspiration/">inspiration</a></li>
		<li><a href="/windows/">windows</a></li>
		<li><a href="/gift/">gift</a></li>
		<li><a href="/gaming/">gaming</a></li>
		<li><a href="/mac/">mac</a></li>
		<li><a href="/osnews/">osnews</a></li>
		<li><a href="/c64/">c64</a></li>
		<li><a href="/linux/">linux</a></li>
	</ul>
	<a rel="previous" href="/code/uth7_floaty-abbrs">
		older article →
	</a><a rel="next" href="/code/it_figures">
		← newer article
	</a></nav>
</header>
<!-- =================================================================================================================== -->
<article><header>
	<!-- date published or updated -->
	<time pubdate datetime="2009-06-07T15:13:00+01:00">
		<sup>3:13<abbr>pm</abbr> • 2009</sup>
		<abbr title="June">Jun</abbr> 7
	</time>
	<!-- categories -->
	<ul>
		<li><a href="/code/php_directory_sorting" rel="bookmark tag">code</a></li>
		<li><a href="/web-dev/php_directory_sorting">web-dev</a></li>
	</ul>
	<!-- licence -->
	<small>
		<a rel="license" href="http://creativecommons.org/licenses/by/3.0/deed.en_GB">c</a>
		share + remix
	</small>
</header>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<section>
<h1>Sorting a Directory Listing Folders First, Then by File Type, Then by Name in PHP</h1>
<p>
	<strong>Something I think might be useful to people.</strong> This code takes a directory listing and then sorts the
	contents listing folders first (in alphabetical order), then the files are sorted by file type and then
	alphabetically for each file type.
</p>

<pre><code>//directory to list, you choose; here we’ll just use the webroot
$path = $_SERVER['DOCUMENT_ROOT'];

//warning: `is_dir` will need you to change to the parent directory of what you are testing
//see &lt;uk3.php.net/manual/en/function.is-dir.php#70005&gt; for details
chdir ($path);

//get a directory listing
$dir = array_diff (scandir ('.'),
	//folders / files to ignore
	array ('.', '..', '.DS_Store', 'Thumbs.db')
);

//sort folders first, then by type, then alphabetically
usort ($dir, create_function ('$a,$b', '
	return	is_dir ($a)
		? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1)
		: (is_dir ($b) ? 1 : (
			strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) == 0
			? strnatcasecmp ($a, $b)
			: strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION))
		))
	;
'));

//echo to screen
header ('content-type: text/plain');
print_r ($dir);</code></pre>

<p>
	Here’s how this breaks down:
</p><p>
	<a href="http://uk3.php.net/manual/en/function.usort.php" rel="external"><code>usort</code></a> sorts an array
	using another function given two items to compare. Return “-1” if the first should go above the other, 1 if the
	second should go above the other and 0 if they are equal.
</p><p>
	We create a function with <code>$a</code> and <code>$b</code> parameters corresponding to the two items being
	compared for sorting as it goes through the list.
</p>

<pre><code>return	is_dir ($a)</code></pre>

<p>
	If the first item is a directory then…
</p>

<pre><code>? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1)</code></pre>

<p>
	Check if the second item is a directory. If both items are directories then compare them by name.
	<a href="http://uk2.php.net/manual/en/function.strnatcasecmp.php" rel="external"><code>strnatcasecmp</code></a>
	will return “-1”, “0” or “1” accordingly.
</p>

<pre><code>: (is_dir ($b) ? 1 : (</code></pre>

<p>
	Now if the first item is not a directory, check if the second item is. If the second item is a directory, it will go
	above the first item—return “1”.
	<br /><br />
	Else, compare file extensions
</p>

<pre><code>strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) == 0</code></pre>

<p>
	If the file extensions are equal then compare the file names
</p>

<pre><code>? strnatcasecmp ($a, $b)</code></pre>

<p>
	Finally, if the file extensions are not equal, compare them again, this time returning the result
</p>

<pre><code>: strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION))</code></pre>

<p>
	And that’s it!
	<br /><br />
	Enjoy.
</p>
</section>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
</article>
<footer>
	<nav><a href="http://forum.camendesign.com">‹ Discuss this in the Forum ›</a></nav>
		
	<a href="mailto:kroc@camendesign.com">kroc@camendesign.com</a>
	<nav>view-source:
		<a href="/code/php_directory_sorting.rem">Rem</a> •
		<a href="/code/php_directory_sorting.html">HTML</a> •
		<a href="/design/">CSS</a> •
		<a href="/.system/">PHP</a> •
		<a href="/.htaccess">.htaccess</a>
	</nav>
	<form method="get" action="https://duckduckgo.com">
		<input type="hidden" name="sites" value="camendesign.com" />
		<input type="search" name="q" placeholder="search…" />
		<input type="submit" value="Go" />
	</form>
</footer>
<!-- =================================================================================================== code is art === -->