BittyWiki

Just for grins, and to flex my PHP chops, I decided to write a simple wiki system. The catch, though, is to see how short I can make the actual program; I was inspired by this Shortest Wiki Contest, though I can’t profess to be quite as fanatic as those guys (I prefer readable code—squishing it all into a minimal number of obfuscated lines just seems like cheating), I think I did pretty well so far. Read through if you’re interested; it’s pretty technical and I include the PHP source.

The BittyWiki, as I’m calling it, is pretty limited by most wiki standards: it stores the content in flat files, doesn’t do any sort of version control, or change/revision tracking, or provide a formatting scheme for text other than a subset of HTML. But it works, and I’ve sandboxed a bit of the functionality for basic sanity checking. And it all runs out of one file, index.php. All you’d need to do is upload that to your server, create a writeable data directory alongside it, and point your browser at it.

Links need to be structured in the form of index.php?page=pagename in the anchor tags, so the user would have to know some HTML to add pages to the system. And there’s a basic safeguard against file spoofing here by taking the basename() of the page name (it’s basically a user parameter, after all) and stripping all but alphanumerics and a few extra characters so we don’t break the filesystem when we try to create/open the file.

Really, this is nearly as simple as I can make it, there’s already even a TODO in a comment there that would add some complexity. I could shed a few more bytes by shortening up some functions (using file() instead of the fopen() stuff, reducing the number of allowable HTML tags), but that’s a bit pedantic, and I rather think it’s kind of elegant the way it is.

Here’s the source (created using PHP’s built-in highlight_file() function and copying-and-pasting). Disclaimer: If you copy this code to your server and it breaks something, don’t come crying to me :).

<?php

/**
*  BittyWiki
*
*  How small can I make a functional wiki using PHP?
*  If I attach a stylesheet, should that count against size?
*/

$page = basename($_GET[‘page’]);

// Make sure $page is file-safe
$page = preg_replace(‘/[^a-zA-Z0-9._-]+/’, , $page);
$page = (!empty($page))? $page: ‘index.php’;
$filename = ‘data/’ . $page;

if ( !empty($_POST) ) {
    $data = $_POST[‘data’];
    // TODO: Only grab stuff between <body> tags
    $data = strip_tags($data, ‘<p>,<br>,<a>,<b>,<i>,<h1>,<h2>,<h3>,<h4>,<h5>,<h6>,<ul>,<ol>,<li>,<blockquote>’);
    $fp = fopen($filename, ‘w’);
    fwrite($fp, htmlspecialchars(strip_tags($_POST[‘title’])) . “n~n” . $data);
    fclose($fp);

    // Redirect to itself to avoid the refresh problem
    header(“Location: index.php?page=$page”);
    exit;
}

if ( file_exists($filename) ) {
    $fp = fopen($filename, ‘r’);
    $data = fread($fp, filesize($filename));
    fclose($fp);
    list($title, $data) = explode(“n~n”, $data, 2);
}

if ( $_GET[‘action’] == ‘edit’ ) {
?>

<html><head><title>BittyWiki: Edit <?php echo $page; ?></title></head>
<body><form method=”post” action=”index.php?page=<?php echo $page; ?>“>
<h1>Edit <?php echo $page; ?></h1>
Title:<br />
<input type=”text” name=”title” size=”100″ value=”<?php echo htmlspecialchars($title); ?>” /><br />
Body:<br />
<textarea name=”data” cols=”100″ rows=”25″><?php echo htmlspecialchars($data); ?></textarea><br />
<input type=”submit” value=”Save” />
</form></body></html>
<?php

} else {

?>
<html><head><title>BittyWiki: <?php echo $title; ?></title></head><body>
<?php echo $data; ?>
<hr />
<p><a href=”index.php?page=<?php echo $page; ?>&action=edit”>Edit this page</a></p>
</body></html>
<?php

}

?>

4 comments

  1. Man, that is pretty tidy. Now just remove all but the necessary whitespace, use shorthand versions of some of that stuff (as I think both echo and print have shorthand versions, as does some other stuff — php guru I am not, so I may be totally wrong here), and you might be able to knock like 300 bytes off there 😉

    Oh, and use HTML 3.2 output (or just even 4) so you don’t have to have extra space and the closing "/" on some tags.

  2. Create A Wiki with Four Lines of Code?
    SigWik is a Wiki that only has four lines of source code. Other programming fanatics have created 12 others that are all under 50 lines of code (in languages such…

  3. I was leaning towards XHTML compliance with the extra "/" for closing tags, but there’s really no reason for it. echo and print don’t have shorthand versions per se, but I believe you can configure PHP to mimic ASP’s <%= shortcut tag for outputting, but I’d prefer to stick to pure PHP 🙂

Comments are closed.