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
}

?>

Posted by jon at 12:29 AM



Comments:

Jake writes:

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.


UtterlyBoring.com writes:

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...


Jon writes:

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 :-)


Jake writes:

See, that's what I used. My PHP is configured to