Using a class and AJAX!
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Tue, 25 Oct 2011 22:24:36 +0200
changeset 2 def69d70eb6e
parent 1 ae829f97a638
child 3 6d109e3804ac
Using a class and AJAX!
.htaccess
addressbook.class.php
index.php
--- /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>
 
 <? } ?>