Skip to content

Instantly share code, notes, and snippets.

@spajak
Last active March 8, 2022 18:04
Show Gist options
  • Save spajak/68738e00376e88e2e3f0ba65201733ec to your computer and use it in GitHub Desktop.
Save spajak/68738e00376e88e2e3f0ba65201733ec to your computer and use it in GitHub Desktop.
Lighttpd simple PHP example of directory listing with custom HTML/CSS template
<?php
/*
* Simple directory listing for a web server (lighttpd).
*
* Author: Sebastian Pająk
* Version: 0.0.1
* License: MIT
*
* Setup:
*
* Make sure you have `mod_fastcgi` enabled and configured.
* Add the following line to the lighttpd config:
* index-file.names = ("/.dir.php")
*
* Copy both files `.dir.php` and `.dir.tmpl` into document root.
* Feel free to edit the files to your needs.
*/
define('TEMPLATE', ".dir.tmpl");
define('REQUEST_URI', $_SERVER['REQUEST_URI'] ?? '/');
define('DEFAULT_ORDER', 'name'); // `date` (desc) or `name` (asc)
function main()
{
$dir = getDir();
$files = getFiles($dir);
header('content-type: text/html; charset=utf-8');
include TEMPLATE;
}
function getDir()
{
list($dir) = explode("?", REQUEST_URI);
$dir = trim($dir, "/");
if (strlen($dir) > 0) {
$dir .= "/";
}
$dir = "./".$dir;
if (!is_dir($dir)) {
throw new RuntimeException(sprintf('Not a directory "%s"', $dir));
}
return $dir;
}
function makeRecord(object $file)
{
$record = new stdClass;
$record->name = $file->getFilename();
$record->type = $file->getType();
$record->size = $file->isDir() ? '–' : $file->getSize();
$record->date = date('Y-m-d H:i:s', $file->getMTime());
if ($file->isDir()) {
$record->name .= '/';
}
return $record;
}
function getFiles(string $dir, string $order = null)
{
if (!isset($order)) {
$order = DEFAULT_ORDER;
}
$result = [];
foreach (new DirectoryIterator($dir) as $file) {
if (!$file->isReadable()) {
continue;
}
$name = $file->getFilename();
if (strpos($name, '.') === 0) {
continue;
}
$result[] = makeRecord($file);
}
uasort($result, function($a, $b) use ($order) {
if ($order === 'date') {
return -1 * strcasecmp($a->date, $b->date);
}
return strcasecmp($a->name, $b->name);
});
return $result;
}
main();
<!DOCTYPE html>
<html>
<head>
<title>[share] <?= $dir ?></title>
<style>
body {margin: 16pt; padding: 0; font-family: monospace; font-size: 100%; line-height: 1.25; background-color: white; color: black;}
h1 {font-size: 1.5em; margin: 0.375em 0;}
td {padding-right: 1.25em;}
.r {text-align: right;}
.t-dir {color: blue;}
</style>
</head>
<body>
<h1><?= $dir ?></h1>
<table>
<?php foreach ($files as $file): ?>
<tr>
<td class="t-<?= $file->type ?>"><?= $file->name ?></td>
<td class="r"><?= $file->date ?></td>
<td class="r"><?= $file->size ?></td>
</tr>
<?php endforeach ?>
</table>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment