Class Loader

Filed in Lab Leave a comment

I needed a class loader for my little framework as I dont want to include all the files in on every request which is what listing them in a long list of includes will do. So I checked out the PHP.net site which has this code sample. I used it as a starting point for this:

function __load_class($classname, $dir)
{
	$file = $dir . '/' . $classname . '.php';
	if (file_exists($file))
	{
		require_once ($file);
		return true;
	}
	return false;
}
 
function __autoload($classname)
{
	$inc[] = '../fwork';
	$inc[] = '../fwork/controllers';
	$inc[] = '../fwork/models';
	$inc[] = '../app';
	$inc[] = '../app/controllers';
	$inc[] = '../app/models';
 
	foreach ($inc as $dir)
	{
		if (__load_class($classname, $dir))
		{
			if(DEBUG_LEVEL == 2)
			{
				echo 'Loading class(' . $classname . ")<br>";
			}
			return;
		}
	}
}

I need to do some more testing and abstraction but its a good start for what I need.

Mod_rewrite

Filed in Lab Leave a comment

I wanted to start a small MVC framework to help build my next project. I needed to get mod_rewrite working and also build a simple class loader.

For mod_rewrite I setup the following .htaccess file (xp.htaccess to get around Windows’ filename issue)

RewriteEngine on
RewriteCond %{REQUEST_URI} !\.(php|css|js|gif|png|jpe?g)$
RewriteRule (.*)$ /index.php [L]

Then in my dispatcher file I can read the contents of the query string like this:

$request_uri = explode('/', $_SERVER['REQUEST_URI']);
$controller = htmlentities($request_uri[1]);
$action = htmlentities($request_uri[2]);
if($action == '') {$action = 'index'; }
$param = htmlentities($request_uri[3]);
if($param == '') {$param = ''; }

This is just temporary code and used to prove that it would work the way I expected. Sort of like tracer bullets described in The Pragmatic Programmer. But now I can use a URL like:

http://recipemanager/ingredient_type/update/5

Which will then let me know that I need to access the ingredient_type controller pass the parameter 5 to the update method.

Zend Framework

Filed in Lab Leave a comment

Anthony suggested that I try out the Zend Framework. It’s a pretty simple installation but I had a hard time findinga decent tutorial. The simple starter on the Zend site is set up to use SQL Lite and I just did not feel like installing and learning that at the same time. Then I stumbled upon this one that is quite good. Once you have completed it you will have a working CRUD for a single table. I found a couple of problems in the documentation vs. the example code though.

The tutorial shows how to set up your Apache virtual server for the project

ServerName zf-tutorial.localhost
DocumentRoot /var/www/html/zf-tutorial/public
AllowOverride All

This means that the server would serve files from the public directory. It then goes on to say to put the bootstrap (index.php) under the public directory. I was having some problems so I downloaded the example code to compare it with what I had done. I noticed that in the example code the index.php file was under the parent directory of public. This means the virtual host entry is wrong as it should point to zf-tutorial not public. I decided to leave the bootstrap file in the public directory as I did not want to have public access to the root of the application.

<?php
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors', 1);
date_default_timezone_set('Europe/London');
 
include('../helpers/print_var.php');
include('../helpers/MyIterator.php');
 
 
// directory setup and class loading
set_include_path('.' . PATH_SEPARATOR . '../library/'
. PATH_SEPARATOR . '../application/models'
. PATH_SEPARATOR . get_include_path());
 
include "Zend/Loader.php";
Zend_Loader::registerAutoload();
 
// load configuration
$config = new Zend_Config_Ini('../application/config.ini', 'general');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);
 
// setup database
$db = Zend_Db::factory($config->db);
Zend_Db_Table::setDefaultAdapter($db);
 
// setup controller
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory('../application/controllers');
 
Zend_Layout::startMvc(array('layoutPath'=>'../application/layouts'));
 
// run!
$frontController->dispatch();

Autocomplete field with jQuery and PHP

Filed in Lab Leave a comment

For the recipe manager project I need to allow the entering of ingredients that the system does not know about. I decided to use an auto complete field to allow users to easily see what was already in the system. If the ingredient does not exist then the one they entered will added to the system.

To test this out I wrote a quick little program that assigns employees to an assigned employees table. The autocomplete does a look up in the employees table. If the entered employee is not found then the new employee is added to the employees table and then assigned.

I used the following jQuery stuff:

jQuery1.2.6
Autocomplete – jQuery plugin 1.0.2 (copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer)

Main interface: index.php

<?php
 
	include('config.php');
	$employees = array();
	$assigned_employees = array();
 
 
	$query = "select * from employees";
	$result = mysql_query($query) or die('Query failed: ' . mysql_error());
	while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) 
	{
		$employees[$line['id']] = $line['first_name'];
	}	
 
	$query = "select * from assigned_employees";
	$result = mysql_query($query) or die('Query failed: ' . mysql_error());
	while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) 
	{
		$assigned_employees[$line['id']] = $line['first_name'];
	}
 
?>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<script src="../javascript/jquery-latest.js"></script>
 	<link rel="stylesheet" href="../javascript/jquery.autocomplete.css" type="text/css" />
	<script type="text/javascript" src="../javascript/jquery.autocomplete.js"></script>
	<script>
		$(document).ready(function()
		{
			// var data = "Core Selectors Attributes Traversing Manipulation CSS Events Effects Ajax Utilities".split(" ");
			$("#first_name").autocomplete('autocomplete.php');
 
			$("#first_name").result(function() 
			{
				console.log(arguments);
			}
			);
		}
		);
  </script>
 
</head>
<body>
	<form action="insert.php" method="post">
		Assigned an employee: <input id="first_name" name="first_name" />
		<input type="submit" value="Submit" />
	</form>
 
	<h3>Employees</h3>
<?php
	foreach($employees as $employee)
	{
		echo "$employee <br>";
	}
?>	
 
<h3>Assigned Employees</h3>
<?php
	foreach($assigned_employees as $employee)
	{
		echo "$employee <br>";
	}
?>
 
<div>--------------------------------------------</div>
<a href="clear.php">Remove all assignments</a>
 
</body>
</html>

Auto Complete Function: autocomplete.php

<?php
include('config.php');
 
$q = $_GET['q'];
 
// Performing SQL query
$query = "SELECT id, first_name FROM employees";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
 
 
while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) 
{
	if (substr($line['first_name'], 0, strlen($q)) == $q) 
	{
		echo $line['first_name'] .'|'. $line['id'] . "\n";
	}
}
 
?>

Insert Function: insert.php

<?php
include('config.php');
 
//get the first_name from the form
$first_name = $_POST['first_name'];
 
// see if we have it in the database. If so then grab the ID
$query = "SELECT id FROM employees WHERE first_name = '$first_name'";
 
//print "$query<br>";
 
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
 
if(!$row = mysql_fetch_assoc($result))
{
	// If not then insert it into the employees  table. Then get the ID of the new employee from the employees table.
	$query = "INSERT INTO employees(first_name) VALUES('$first_name')";
	//print "$query<br>";
	$result = mysql_query($query) or die('Query failed: ' . mysql_error());
 
	$id = mysql_insert_id();
}
else
{
	$id = $row['id'];
}
 
// Now insert into the ingredient list table.
 
$query = "INSERT INTO assigned_employees(id, first_name) VALUES($id, '$first_name')";
//print "$query<br>";
 
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
 
header( 'Location: http://localhost/lab/autocomplete/index.php' ) ;
 
?>

Clear Function: clear.php

<?php
include('config.php');
 
$query = "delete FROM assigned_employees";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
header( 'Location: http://localhost/lab/autocomplete/index.php' );
?>

Database Schema

CREATE DATABASE /*!32312 IF NOT EXISTS*/`test` /*!40100 DEFAULT CHARACTER SET latin1 */;
 
USE `test`;
 
/*Table structure for table `assigned_employees` */
 
DROP TABLE IF EXISTS `assigned_employees`;
 
CREATE TABLE `assigned_employees` (
  `id` INT(10) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(64) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
 
/*Data for the table `assigned_employees` */
 
INSERT  INTO `assigned_employees`(`id`,`first_name`) VALUES (0000000002,'sam');
 
/*Table structure for table `employees` */
 
DROP TABLE IF EXISTS `employees`;
 
CREATE TABLE `employees` (
  `id` INT(10) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
 
/*Data for the table `employees` */
 
INSERT  INTO `employees`(`id`,`first_name`) VALUES (0000000001,'steve'),(0000000002,'sam'),(0000000003,'heather'),(0000000004,'heath'),(0000000005,'shamus'),(0000000006,'jennifer'),(0000000007,'geronimo'),(0000000008,'gerald');
 
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;

,

TOP