--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.htaccess Tue Oct 25 22:24:36 2011 +0200
@@ -0,0 +1,1 @@
+php_flag display_errors 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/addressbook.class.php Tue Oct 25 22:24:36 2011 +0200
@@ -0,0 +1,75 @@
+<?
+interface AdressBook_Interface {
+ public function get_entries();
+ public function search_entries($pattern);
+ public function add_entry($entry);
+}
+
+class AddressBook implements AdressBook_Interface {
+
+ const RS = "\n";
+ const FS = "\t";
+
+ private $fh;
+ private $file;
+
+ function __construct($file) {
+ @mkdir(dirname($file));
+ $this->fh = fopen($file, "a+b");
+ flock($this->fh, LOCK_EX);
+ $stat = fstat($this->fh);
+ if ($stat['size'] == 0) {
+ fputs($this->fh, join(self::FS, array("Hans Hanson", "0815", "hans@hanson.de"))
+ . self::RS);
+ }
+ flock($this->fh, LOCK_SH);
+ fseek($this->fh, 0, SEEK_SET);
+ }
+
+ function get_entries() {
+ $entries = array();
+ fseek($this->fh, 0, SEEK_SET);
+ while($line = stream_get_line($this->fh, 0, self::RS)) {
+ if ($line === FALSE) break;
+ $entries[] = explode(self::FS, $line);
+ }
+ return $entries;
+ }
+
+ function add_entry($entry) {
+ $fields = array('name', 'tel', 'mail');
+
+ $new = array();
+ foreach($fields as $key) {
+ if (!isset($entry[$key])) return false;
+ $new[$key] = trim($entry[$key]);
+ $new[$key] = preg_replace('/['.self::RS.self::FS.' ]+/', ' ', $new[$key]);
+ if (empty($new[$key])) return false;
+ }
+
+ flock($this->fh, LOCK_EX);
+ fputs($this->fh, join(self::FS, $new) . self::RS);
+ flock($this->fh, LOCK_UN);
+
+ return true;
+ }
+
+ function search_entries($pattern) {
+ $pattern = trim($pattern);
+ if (empty($pattern)) return;
+ $pattern = preg_replace('/\//', '\/', $pattern);
+ fseek($this->fh, 0, SEEK_SET);
+ $entries = array();
+ while ($line = stream_get_line($this->fh, 0, self::RS)) {
+ if ($line === FALSE) break;
+ if (!preg_match("/$pattern/i", $line)) continue;
+ $entry = explode(self::FS, $line);
+ $entries[] = array('name' => $entry[0],
+ 'tel' => $entry[1],
+ 'mail' => $entry[2]);
+ }
+ return $entries;
+ }
+}
+
+?>
--- a/index.php Tue Oct 25 16:45:47 2011 +0200
+++ b/index.php Tue Oct 25 22:24:36 2011 +0200
@@ -1,98 +1,85 @@
<?php
-const FILE = "var/abook.txt"; // parent dir must exist
-const RS = "\n";
-const FS = "\t";
-
-function open_db($file) {
- @mkdir(dirname($file));
+const FILE = "var/abook.txt";
- $fh = fopen($file, "a+b");
- flock($fh, LOCK_EX);
- $stat = fstat($fh);
- if ($stat['size'] == 0) {
- fputs($fh, join(FS, array("Hans Hanson", "0815", "hans@hanson.de"))
- . RS);
- }
- flock($fh, LOCK_SH);
- fseek($fh, 0, SEEK_SET);
-
- return $fh;
-}
+require 'addressbook.class.php';
-function get_entries($fh) {
- $entries = array();
- fseek($fh, 0, SEEK_SET);
- while($line = stream_get_line($fh, 0, RS)) {
- if ($line === FALSE) break;
- $entries[] = explode(FS, $line);
- }
- return $entries;
-}
-
-function add_entry($fh, $entry) {
- $fields = array('name', 'tel', 'mail');
+$abook = new AddressBook(FILE);
- $new = array();
- foreach($fields as $key) {
- if (!isset($entry[$key])) return;
- $new[$key] = $entry[$key];
- trim($new[$key]);
- preg_replace('/['.RS.FS.' ]+/', ' ', $new[$key]);
- if (empty($new[$key])) return;
- }
-
- flock($fh, LOCK_EX);
- fputs($fh, join(FS, $new) . RS);
- flock($fh, LOCK_UN);
- header("Location: $_SERVER[PHP_SELF]?action=add");
- exit;
-}
-
-function search_entries($fh, $pattern) {
- fseek($fh, 0, SEEK_SET);
- $entries = array();
- while ($line = stream_get_line($fh, 0, RS)) {
- if ($line === FALSE) break;
- if (!preg_match("/$pattern/i", $line)) continue;
- $entry = explode(FS, $line);
- $entries[] = array('name' => $entry[0],
- 'tel' => $entry[1],
- 'mail' => $entry[2]);
- }
- return $entries;
-}
-
-
-$abook = open_db(FILE);
-
-switch ($_REQUEST['action']) {
- case 'add': add_entry($abook, $_REQUEST);
- break;
- case 'search': $entries = search_entries($abook, $_REQUEST['pattern']);
- break;
+switch (@$_REQUEST['action']) {
+ case 'add': if ($abook->add_entry($_REQUEST)) {
+ header("Location: $_SERVER[PHP_SELF]?action=add");
+ exit(0);
+ }
+ break;
+ case 'search': $entries = $abook->search_entries($_REQUEST['pattern']);
+ if (@$_REQUEST['format'] == 'table') {
+ header("Content-Type: text/html; charset=UTF-8");
+ if (!$entries) {
+ echo "Sorry, keine Einträge.";
+ exit(0);
+ }
+ echo "<table><tr><th>Name<th>Tel<th>Mail</tr>";
+ for ($i = 1; $entry = array_shift($entries); $i++) {
+ echo "<tr>"
+ . "<td>" . htmlspecialchars($entry['name'])
+ . "<td>" . htmlspecialchars($entry['tel'])
+ . "<td>" . htmlspecialchars($entry['mail']);
+ if ($i > @$_REQUEST['max']) break;
+ }
+ echo "</table>";
+ if ($entries)
+ echo "<p>Und noch ".count($entries)." weitere Einträge";
+ exit(0);
+ }
+ break;
}
?>
<!-- HTML -->
+<?=header("Content-Type: text/html; charset=UTF-8");?>
<html>
+<head>
+
+<script type=text/javascript>
+ // source: http://de.wikibooks.org/wiki/Websiteentwicklung:_AJAX:_Erstes_Programm
+ var _ajax;
+
+ function got_answer() {
+ if (_ajax.readyState == 4 && _ajax.status == 200) {
+ document.getElementById('result').innerHTML = _ajax.responseText;
+ }
+ }
+
+ function search_entries(value) {
+ value = encodeURIComponent(value);
+ request = "?action=search&format=table&max=3&pattern=" + value;
+ _ajax = new XMLHttpRequest();
+ _ajax.onreadystatechange = got_answer;
+ _ajax.open("GET", request, true);
+ _ajax.send();
+ }
+</script>
<style type="text/css">
form label { display:block; float:left; width:10ex; }
</style>
-<body>
+</head><body>
-<? if ($_REQUEST['action'] == 'add') { ?>
+<? if (@$_REQUEST['action'] == 'add') { ?>
[ <a href="<?=$_SERVER['PHP_SELF']?>">Home</a> ]
<? } else { ?>
[ <a href="<?=$_SERVER['PHP_SELF']?>?action=add">Add Entries</a> ]
<? } ?>
+<div id=debug>
+ DEBUG
+</div>
<h1>Adressbuch</h1>
-<? if ($_REQUEST['action'] == 'add') { ?>
+<? if (@$_REQUEST['action'] == 'add') { ?>
<p>
<form>
<label for=name>Name</label>
@@ -107,13 +94,16 @@
<? } else { ?>
- <form>
- <input type=text name=pattern onChange="submit()" />
- <input type=hidden name=action value=search />
+ <form autocomplete=off>
+ <input type=text name=pattern
+ onKeyUp="search_entries(this.value)"
+ onChange="submit()") />
+ <input type=hidden name=action value=search autocomplete=off />
<noscript><input type=submit /></noscript>
</form>
- <? if ($entries) { ?>
+ <div id=result>
+ <? if (isset($entries) and $entries) { ?>
<table>
<tr><th>Name<th>Telefon<th>Mail</tr>
<? foreach ($entries as $entry) { ?>
@@ -127,6 +117,7 @@
<? } else { ?>
Sorry.
<? } ?>
+ </div>
<? } ?>