Tutorials

Easy Server Side Caching in PHP

Tagged:  

When developing dynamic web applications there may be many times that data is not updated for a certain amount of time. In PHP it is fairly simple to have a page cached, so that there is not much load on the server.

To create this caching you would put some code like the following on the top of your PHP page.

$cachefile = 'caching_folder/cachedpage.html';
$cachetime = 30;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
    include($cachefile);
    exit;
}
ob_start(); // Start the output buffer

The things that you would change in the above code is the setting of the $cachfile variable to the name of the static file that the cache will be saving on the server (you will need to set permissions on the folder where you want to save the cached file). You will also want to change the $cachetime variable to the number of seconds between each caching.

Now you would put all of your standard PHP code to create the page after the above code. Once you have all of your standard PHP code you would put the below code to actually save the cache file.

// Cache the output to a file
$fp = fopen($cachefile, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush(); // Send the output to the browser

This script is very handy and a version of it is used in the del.icio.us Spy application to avoid too many calls to the del.icio.us servers.

Debugging PHP

Tagged:  

Even though I really enjoy developing in PHP there are times that debugging an issue can be very frustrating. I found a good tutorial on debugging PHP.

Below is an excerpt from the tutorial.

Starting with the Basics - Parse Errors

Parse errors can be one of the most irritating bugs for new PHP programmers to solve. A missing quote ("), bracket ({,}), and a multitude of other errors can be thrown by the interpreter which may leave you asking "What is wrong?".

Consider this code:

PHP Code:


<?php

print "Hello World;

?>


You may notice the missing " after World and before ;. When this code is ran it casts the error:

Code:
Parse error: syntax error, unexpected $end in C:\wamp\www\broken.php on line 5

Which may leaving you asking, what is wrong with line 5?

Line 5:

PHP Code:



?> 



The line numbers may be a little deceiving at first, causing a new PHP programmer to overlook the problem. The real issue is caused because the interpreter sees a quote before Hello and assumes a string will follow. With no ending quote, the interpreter reaches the end of the script, but never completes the string assignment.

When such an error is cast, take a look at the actual line first. In this case: ?>. If no immediate errors appear start working your way backwards line-by-line. Do a quick scan of each line making sure you have terminated them correct (;). Make sure matching pairs have an ending pair (in this case the quote).

Examples of matching pairs:
[ ]
{ }
" "
' '

Now consider the following code:

PHP Code:



<?php
$yourName 
"Jordan";

if $yourName == "Jordan")
{
  echo 
"Hello $yourName";
}
?>



At a closer look, you see that line 4 is missing the opening (. When this code is ran the interpreter will produce the following error:

Code:
Parse error: syntax error, unexpected T_VARIABLE, expecting '(' in C:\wamp\www\broken.php on line 4

Notice this error message correctly states the line number where the error occurred which is why it is very important to start on the line number given and work backwards. What actually happened was the interpreter read the "if" keyword and expected an open parenthesis followed by a condition. Instead it read "$yourName", a T_VARIABLE or token. What this message translates into is "While on line 4, I was expecting a '(' but received a variable."

You can view the full tutorial here.

I hope this helps you when you run into an issue coding PHP.

As always, if you find anything cool you can blog about it on this site with your free account (Once logged in click on "Create content" => "Blog entry" and then blog away).

Making the Most of Java 5: Exploring Generics

Tagged:  

Erasure aside, the addition of generics to Java (see intro here) brings added dimension to using types in the language. The most obvious application of generics is the ability to declare homogeneous Collection types, such as Collection<String>, but there are less obvious ones as well. I'll explore some of these in this article.

Type Inference

But first, a little diversion. Generics can be used both at the class level and at the method level in Java. Let's suppose we have a generic method like so:

public <T> T getSomething() { ... }

What happens if we do an assignment to a String?

String s = getSomething();

It compiles just fine. The same is true of the following:

Integer i = getSomething();

What is going on here? As you may have guessed, generic methods have an ability to do type inference, that is, they are able to figure out the type from the context of its use in an assignment expression. Quite a new wrinkle for an explicitly-typed language like Java.

If you define a generic type for a parameter to the method getSomething() that also uses <T>, the type defined by the parameter takes "precedence" over assignment inference.

Type-Inferred Factory Method

As Joshua Bloch pointed out in his "Effective Java Reloaded" presentation at JavaOne 2007, you can use this type inference to simplify the creation of complex generic types using a static factory method. Adding a method to the java.util.HashMap class like

public static <K,V> HashMap<K,V> newInstance() {
     return new HashMap<K,V>();
}

simplifies the creation of a complex HashMap object from

Map<String,List<Integer>> map = new HashMap<String,List<Integer>>();

to a much easier-to-read form like

Map<String,List<Integer>> map = HashMap.newInstance();

Type inference makes this possible.

Type-Safe Factory Method

Often factory methods will have a very general applicability, and so in earlier versions of Java, were forced to return an Object which was expected to be cast to the correct type. A good example of this is the java.lang.reflect.Proxy class which has the method:

public static Object newProxyInstance(ClassLoader loader,
     Class<?>[] interfaces,
     InvocationHandler h) 

Assuming that we only want to use the current ClassLoader and we are proxying using only a single interface, we can genericize this method to the following:

public static <T> T newProxyInstance(Class<T> interface, 
     InvocationHandler h)

(One could also genericize the InvocationHandler class with the generic type <T>, as well, so that the first argument of its invoke method was the correct type). Here interface argument is also functioning as a "type token", providing a guarantee that the factory method will return an instance of the correct type and the implementer with the means to do so (via the cast()). Since the type of the Class parameter passed in determines the type of <T>, it acts as a kind of "hook" to determine the type of the return value. Thus this method will not need to have its return value explicitly cast, and will never throw a ClassCastException.

Another great example of this technique are the various bind() methods for the Binder class in the Google Guice library. The type passed into the bind() method is "hooked" via a generic type to the type passed into the various chained to(), toProvider(), toInstance(), and annotatedWith() methods. Hence a "line of configuration" in a Google Guice Module that would define the dependency injection for a Collection interface would look like:

binder.bind(Collection.class).to(ArrayList.class);

Thanks to the use of a generic type, the parameter to the method to() is guaranteed to be of an assignable type to that of the method bind().

Guarantee of Behavior

A little-known part of the Generics specification is the ability to define conjunctive types, that is, multiple types separated by an '&' operator, when defining a generic bounded type. You can use this to make sure that a parameter to a method implements specific interfaces. For example, let's say that you have a method that takes an implementation of a certain interface MyInterface.

public void doSomething(MyInterface onObject) { ... }

Let's also say that you want the passed-in parameter to also implement java.lang.Comparable and java.io.Serializable so that you could sort and serialize the parameter in the method. How would you do this? Well, you could put guard code in your method and throw an IllegalArgumentException--and document this well--but compile-time errors are much preferable to runtime ones. This is where conjunctive generic types come to the rescue...you can change this method to the following:

public <T extends MyInterface & Comparable<T> & Serializable> 
     void doSomething(T onObject)

Now the caller of the method will get a compile error if they try to pass in an implementation of MyInterface that does not also implement the other two interfaces.

Conclusion

Despite some annoyances to the generics implementation in Java (read: erasure), Generics do bring an extra layer to the type safety of the language that can be used in new and creative ways. Once you get past the gotchas, they make your Java programs safer.

Simple Round Corners in CSS

Tagged:  

If you have developed a web 2.0 application you have probably used some technique to create rounded corners. Well, over at Search-This.com they have put together a good post about techniques for creating rounded corners. The tutorial attempts to make the process of creating rounded corners simple.

Below is an excerpt from the post.

One Size Fits All

We are going to use a single image (20px x 20px) to provide our rounded corners and to save on using different images we will use one image only and simply place each corner into place using the background-position property. The image is completely round but I'll only be showing one quadrant of it at a time and therefore we can supply all four corners with one simple image weighing in at only 300 bytes.

Figure 3

one-round-quadrant.png

The benefit of using a single image is that all corners get loaded immediately after the first corner is drawn so there is virtually no delay.

Cut It Out

You may think that you could simply place the image in the four corners of a rectangular box but things aren't as simple as that. Our box needs to have a background color and as we are using a white corner image we need a white background for our box. However, if we place a transparent corner in the corner of that box then in fact nothing really happens. The reason is that the transparent part of the image lets the white background show through and all we get is the square box we started with.

In order for the corners to work properly the corner of the box must be over the background color of the element outside our current box. We therefore need to drag the round corners outside the box to start with but that presents more problems. Here is a screenshot of what the corners will look like outside the box so you can understand what's going on

Figure 4

simple-screen3.jpg

As you can see we have a problem whatever we do! If the images are inside the rectangle then they become invisible. If they are outside the rectangle then it looks even worse as figure 4 above shows

What we really need is a rectangular box where the four corners are cut-out to give a cross-shaped effect. If we made sure that the cut-out matched the radius of our circle (10px) then we could pop our corners nicely into place.

We can achieve this by nesting an inner box inside our outer box and then dragging it outside of the parent using a negative top and bottom margin. If we also give side padding to the parent and top padding to the child we can get a cut out effect like this.

Figure 5

simple-screen2.jpg

The CSS mark up for this is as follows:

CSS:

  1. * {margin:0;padding:0}
  2. h1 {margin:.5em;}
  3. body {
  4. background:#e5e5e5;
  5. color:#000;
  6. }
  7. .box{
  8. float:left;
  9. background:#fff;
  10. padding:0 10px;
  11. margin:10px;
  12. display:inline;/* IE double margin bug*/
  13. }
  14. .one{width:40%}
  15. .inner{
  16. background:#fff;
  17. padding:10px 0;
  18. margin:-10px 0;
  19. position:relative;
  20. }

Followed by the simple HTML:

CODE:

  1. <div class="box one">
  2. <div class="inner">
  3. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed convallis mauris eu ipsum. Proin volutpat facilisis dui. Sed pretium pulvinar arcu.</p>
  4. </div>
  5. </div>

The next step is to provide four elements and place our corners into position with static positioning. We will be leaving a 10px padding around our box so that we have room to position the corners nicely without affecting the inner content. (Don't be tempted to use absolute positioning because IE is always 1px out when the distance traveled is an odd pixel number. This happens on right and bottom absolutely placed elements and can destroy a layout like this.)

I am going to use a div with nested span to provide elements for the corners but if you wanted to reduce mark up you could use a nested "b" element as suggested by Eric Meyer (although its use for background images is not likely to be very semantic). Using a nested b element would also negate the need for a class as you are unlikely to have any other elements like this on your page. Anyway I am sticking with the div and nested span as it is easier to follow.

The HTML we need for this is as follows:

CODE:

  1. <div class="box one">
  2. <div class="inner">
  3. <div class="top"><span></span></div>
  4. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed convallis mauris eu ipsum. Proin volutpat facilisis dui. Sed pretium pulvinar arcu.</p>
  5. <div class="base"><span></span></div>
  6. </div>
  7. </div>

The extra div and span has been placed inside the .inner element which means we must drag the top corners upwards into the padding area and then outwards into free space so that the transparent corners can show. The reverse process is needed for the bottom corners. There are a couple of "haslayout" bugs to squash on the way and IE6 also needs position relative applied to make the corners show.

The revised CSS and HTML for the whole section is shown below.

CSS:

  1. * {margin:0;padding:0}
  2. h1 {margin:.5em;}
  3. body {
  4. background:#e5e5e5;
  5. color:#000;
  6. }
  7. .box{
  8. float:left;
  9. background:#fff;
  10. padding:0 10px;
  11. margin:10px;
  12. display:inline;/* IE double margin bug*/
  13. }
  14. .one{width:40%}
  15. .inner{
  16. background:#fff;
  17. padding:10px 0;
  18. margin:-10px 0;
  19. min-height:0;/* ie7 haslayout issues fix*/
  20. position:relative;
  21. }
  22. * html .inner{height:1px}/* ie6 haslayout issues fix*/
  23. .top,.base{
  24. margin:-10px -10px 0;
  25. background:url(images/one-round-test2.png) no-repeat left top;
  26. height:10px;
  27. position:relative;
  28. font-size:10px;
  29. }
  30. .base{
  31. background-position:left bottom;
  32. margin:0 -10px -10px;
  33. }
  34. .top span,.base span{
  35. background:url(images/one-round-test2.png) no-repeat right top;
  36. display:block;
  37. height:10px;
  38. font-size:10px;
  39. }
  40. .base span{background-position:right bottom;}

I have also added a content div in the middle just to tidy things up and the revised HTML is as follows:

CODE:

  1. <div class="box one">
  2. <div class="inner">
  3. <div class="top"><span></span></div>
  4. <div class="content">
  5. <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed convallis mauris eu ipsum. Proin volutpat facilisis dui. Sed pretium pulvinar arcu.</p>
  6. </div>
  7. <div class="base"><span></span></div>
  8. </div>
  9. </div>

The font-size:10px in the CSS is there to restrict IE's height to 10px; otherwise it would increase the element to the full current font-size and spoil the effect. The result of the above code can be seen in these live examples:

Example 1

Example 2

Example 3

For ease of use the CSS has been left in the head so that you can view source and inspect it easily.

You can read the full tutorial by clicking here.

So go out there and make those non-stylish rectangular boxes into boxes with rounded corners!

CSS Gradient Text Effect

Tagged:  

Over at Web Designer Wall they have posted a good tutorial on creating a gradient header using CSS. The technique is based on an empty span tag a PNG and the position:absolute CSS property (the technique is 100% CSS, no JavaScript or Flash). Compatible tested browsers include Firefox, Opera, Safari and Internet Explorer.

Below is an excerpt from the tutorial:

How does this work?

The trick is very simple. Basically we are just adding a 1px gradient PNG (with alpha transparency) over the text.

screenshot

The HTML markups

<h1><span></span>CSS Gradient Text</h1>

The CSS

The key point here is: h1 { position: relative } and h1 span { position: absolute }

h1 {
  font: bold 330%/100% "Lucida Grande";
  position: relative;
  color: #464646;
}
h1 span {
  background: url(gradient.png) repeat-x;
  position: absolute;
  display: block;
  width: 100%;
  height: 31px;
}

That’s it! You are done. Click here to view my demo page.

Make it work on IE6

Since IE6 doesn’t render PNG-24 properly, the following hack is required in order to display the transparent PNG (add anywhere in between the <head> tag):

<!--[if lt IE 7]>

<style>
h1 span {
  background: none;
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='gradient.png', sizingMethod='scale');
}
</style>

<![endif]-->

This is why we hate IE 6!

jQuery prepend version (for semantic lovers)

If you don’t want to have the empty <span> tag in the heading, you can use Javascript to prepend the <span> tag. Here is a sample using jQuery prepend method:

<script type="text/javascript" src="jquery.js"></script>

<script type="text/javascript">
$(document).ready(function(){

  //prepend span tag to H1
  $("h1").prepend("<span></span>");

});
</script>

You can view the demo here or download it here. To read the full tutorial click here.

If you make any cool headers using this technique I would love to hear about them. You can either leave them in the comments or blog about them at this blog once you create a free account.

Forcing a File Download in PHP

Tagged:  

I found an interesting tutorial on forcing a file to be downloaded instead of opened with the associated application.

Below is the PHP code that would be called to force the doe\wnload.

<?php
session_cache_limiter('none');
session_start();

function _Download($f_location, $f_name){
    str_replace('/', $f_name); 
    str_replace('/', $f_location); 
    header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Length: ' . filesize($f_location));    header('Content-Disposition: attachment; filename=' . basename($f_name));
    readfile($f_location);
}

$file = $_GET['file'];
$loc = $_GET['location'];

downloadFiles($loc, $file);

?>

To use this file, create a link to your download file, lets assume it is download.php. Just reference the link to download.php?file=filename.txt&location=filename.txt. Using the URL parameters the file is passed in and this then forces the download.

This is a great script to for forcing downloads of images, web pages or text files as these would otherwise be opened in the browser.

To view the full tutorial click here

Graceful handling of anchors with jQuery

Over at Hainhealt.com they have an interesting post on handling anchors gracefully with jQuery.

Below is an excerpt from the post:

I've come to use this quite often which eventually leads to a considerable amount of if statements.

Which is ugly. And since I don't like ugliness, I've coded myself a small anchor handler for jQuery. Looking at the code I think I could quite easily make it compatible with the Prototype framework too, but I'll keep that for another post :D

(function(){
  url = window.location.href, handlers = [];

  jQuery.extend({
    anchorHandler: {
      add: function(regexp, callback) {

        if (typeof(regexp) == 'object') {
          jQuery.map(regexp, function(arg){

            args = {r: arg[0], cb: arg[1]};});}

        else  args = {r: regexp, cb: callback};

        handlers.push(args);
        return jQuery.anchorHandler;
      }

    }
  })(document).ready(function(){
    jQuery.map(handlers, function(handler){

      match = url.match(handler.r) && url.match(handler.r)[0] || false;

      if (match) {
      	handler.cb.apply(this, [match, (url.match(/#.*/)[0] || false)]);

      }});});
})();

And I can add triggers like this:

$.anchorHandler
  .add(/\/\#ch\-cheatsheet/,    h.comment.showCheatsheet)

  .add(/\/\#comment\-compose/,  h.comment.showCompose)
  .add(/\/\#comment\-\d+/,      h.comment.focus);

The first argument is a regular expression or a string that is passed to the function match, the second argument is the callback function.

The method also accept arrays as argument like this:

$.anchorHandler.add([
  [/\/\#ch\-cheatsheet/,   h.comment.showCheatsheet],

  [/\/\#comment\-compose/, h.comment.showCompose],
  [/\/\#comment\-\d+/,     h.comment.focus]]);

The callback function receive 2 arguments. The matched bit of the anchor with the anchor itself.

Read the full post here.

This technique is very useful for downgrading your applications on browsers where JavaScript is disabled.

Object Oriented JavaScript - Should You Use It? - Part 2

This is the continuation of a post that I wrote yesterday (click here to read the original post). This post will go into much more depth and will be a bit more technical.

Now to begin to answer the question of should you use object oriented JavaScript (don't worry I will touch on the fact that we have all already used JavaScript objects). The first thing that we should understand is how it is used and what are the advantages or disadvantages. If you have been programming in a language like C++ or Java then you are use to a class style of object oriented. JavaScript does not use this structure, instead an object in JavaScript is based on functions and properties.

JavaScript object oriented programming can be noted in different styles.

The first type of notation is to use the new operator along with the Object() method.

person = new Object()
person.name = "John Doe"
person.height = "6Ft"

person.run = function() {
	this.state = "running"
	this.speed = "4ms^-1"
}

In the above code we define an object named person and then add it's own properties. Also the property person.run will execute the function.

The next notation will be familiar if you have ever used JSON. The below notation is referred to as literal notation. This notation simplifies things a bit and this is much better for sending over the web in an Ajax application where such things really matter.

var rectangle = { 
	upperLeft : { x : 2, y : 2 },
	lowerRight : { x : 4, y : 4},
	method1 : function(){alert("Method had been called" + this.upperLeft.x)}
};

The shortcoming with this method is that it does not lend as well to re-usability.

So far you are probably thinking that this is a waste of time and that why would I ever use this, outside of JSON. Well, now we will start to see the power of this coding style which is in re-usability.

The below example will create an object and will set the value of the name property.

function cat(name) {
	this.name = name;
	this.talk = function() {
		alert( this.name + " say meeow!" )
	}
} 

cat1 = new cat("felix")
cat1.talk() //alerts "felix says meeow!"

cat2 = new cat("ginger")

The above code shows how you can easily create multiple objects based on the same object. Which brings me to how you have already used object oriented JavaScript. For example the document.getElementById() method is an example of an object that you more than likely have used (don't worry Prototype library lovers, I'll touch on $() in just a moment).

One of the great things with objects is that using prototype (if you have been programming in ActionScript you will be familiar with the below) you can now extend the functionality of an existing object in a new object.

The below code is an example of how to use prototype to extend an object.

cat.prototype.changeName = function(name) {
	this.name = name;
}

firstCat = new cat("pursur")
firstCat.changeName("Bill")
firstCat.talk() //alerts "Bill says meeow!"

Using prototype you can extend existing JavaScript objects, such as the date (I believe that this is how the prototype library creates the $() method which is in essence the document.getElementById() method) object.

The below example shows how to extend array object with the shift and unshift methods that are not available in some browsers.

if(!Array.prototype.shift) { // if this method does not exist..

	Array.prototype.shift = function(){
		firstElement = this[0];
		this.reverse();
		this.length = Math.max(this.length-1,0);
		this.reverse();
		return firstElement;
	}
	
}

if(!Array.prototype.unshift) { // if this method does not exist..
	
	Array.prototype.unshift = function(){
		this.reverse();
		
			for(var i=arguments.length-1;i>=0;i--){
				this[this.length]=arguments[i]
			}
			
		this.reverse();
		return this.length
	}
}

If you have been programming in a language link C++ or Java you are probably very familiar with a class structure. Part of this is the idea of a class and a subclass. While most JavaScript object oriented code will not use the following, below is an example of how you can create classes and subclasses in JavaScript.

function superClass() {
  this.supertest = superTest; //attach method superTest
}

function subClass() {
  this.inheritFrom = superClass;
  this.inheritFrom();
  this.subtest = subTest; //attach method subTest
}

function superTest() {
  return "superTest";
}
  
function subTest() {
  return "subTest";
}


 var newClass = new subClass();

  alert(newClass.subtest()); // yields "subTest"
  alert(newClass.supertest()); // yields "superTest"

So, now that you have seen how you can extend and reuse JavaScript objects it still leaves us with the question of should you use it. If you need to create code that needs to be reused or extended then it should be a JavaScript object. If you are just writing code that does a few lines of code that doesn't need to be reused or extended then procedural (a.k.a. typical function style code) style code is fine to use. So, the answer to the question is yes in many cases although there are times when it may be overkill.

The next post will take a look at how JavaScript will soon be changing once (or some would say if) ECMAScript 4 starts getting major browser support.

So, as always if you have any questions leave a comment or you can private message me once you add me to your buddy list (I will add you as a buddy as soon as I see the request) that is available once you login. Also, if you would like to write anything on this blog you can do so once you login by clicking on create content and then blog entry. The most interesting posts will be promoted to the home page.

many of the above code samples where taken from this post on JavaScript Kit.

PHP Templating

Tagged:  

If you've done any developing with PHP (especially with open source PHP projects) you will have probably at least seen some templating. A commonly used template engine for PHP is Smarty. Smarty does a good job of helping your PHP applications adhere to a Model View Controller design.

As you probably know Model View Controller is a way of abstracting portions of an applications so that you can have multiple people working on their part of the project without stepping on other peoples toes. Which in any decent sized organization (or even in a startup) is very helpful to the development process. If you develop in PHP I recommend that you use templating, even in Ajax applications with PHP on the backend I recommend using templating, as it helps abstract the design from both the backend code and the data (which is exactly what we want).

Just to get you started with templating I've included a portion of a good tutorial on templating using Smarty below.

Basic Templating

At the most basic level, templating can be achieved by removing the common HTML code into separate files and including them into any php file:

<?php include("header.php"); ?>
some content and html goes here
<?php include("footer.php"); ?>

This approach is fine for most purposes and does help reusing common HTML (and/or php) code, for menu generation and setting of page footers and headers. Unfortunately, it does not adapt particularly well to all situations. In the event of the page dealing with form handling or session usage, life becomes slightly more complex.

The relatively simple form below shows how the code can become relatively messy and difficult to follow.

<?php
session_start();
require_once("header.php");

if(isset($_SESSION['username'])) {
   echo "Logged in as : " . $_SESSION['username'];
}
if(isset($_POST['id'])) {
   $results = database_query("SELECT * FROM blah WHERE id = ?", Array($_POST['id']));
   if(sizeof($results>0)) {
      echo "<p>The following matches were found:</p>";
      echo "<ul>\n";
      foreach($results as $item) {
         echo "<li>" . $item . "</li>\n";
      }
      echo "</ul>\n";
   }
   else {
      echo "<p>No matches found.</p>";
   }
}
?>
<p>Please enter an ID to search for</p>
<form method='post'>
<input type='text' name='id' value=''>
<input type='submit'>
</form>
<?php
require_once("footer.php");
?>

Fom looking at the above code, we have the following problems :

* We have to do some things before we can include the header page (e.g. session_start() or header() calls).
* Ideally we should only be outputting HTML at the last possible moment
* We have a mixture of PHP and HTML code, which makes the file bulky and difficult to edit
* It wouldn't be very easy to use the same underlying code to generate a page as a .pdf or other format
* Upon adding more logic, it's likely that it will become harder to follow the flow of execution
* The over complex nature of the page means it's highly likely that bugs will be introduced

We can help to solve the above problems by splitting the page into two distinct parts :

* Logic (dealing with form parameters and data retrieval)
* Display (HTML or other output).

Smarty has the answer...

There are numerous templating engines available for PHP, and some projects have the discipline to use native PHP embedded within a file for display of logic. I found Smarty's existing documentation and framework to make the migration far easier, as well as forcing me to resist the temptation to embed PHP based logic within the template.

Smarty is written in PHP, and installation is a matter of downloading a compressed file, extracting it somewhere appropriate (E.g. /usr/local/lib/php) and creating the necessary directory structure within your project. In order to use Smarty from within a PHP page, the following is required :

<?php
require_once("path/to/Smarty.class.php");
$smarty = new Smarty();
....
?>

Jumping straight to the refactored example, the way Smarty can be used, and the benefits of it should become clear.

First, the template file which is used by Smarty (this will normally live in a directory called 'templates'). This file contains HTML markup and some simple Smarty specific syntax. This file has a suffix of .tpl. An example one follows :

{include file='header.php'}
<p>Welcome to the application</p>

{if isset $logged_in_as}
    <p>{$logged_in_as}</p>
{/if}

{if sizeof($results > 0)}
    <ul>
    {foreach from=$results item=i}
       <li>{$i}</li>
    {/foreach}
    </ul>
{/if}
<p>Please enter an ID to search for</p>
<form method='post'>
  <input type='text' name='id' value=''>
  <input type='submit'>
</form>
{include file='footer.php'}

As you can see, Smarty provides constructs for looping and checking for the existence of variables. Smarty's template language is very similar to PHP in many respects.

In order to populate this template, the following php code could be used :

<?php
require_once("path/to/Smarty.class.php");
$smarty = new Smarty();
if(isset($_SESSION['username'])) {
   $smarty->assign("logged_in_as", "You are logged in as " . $_SESSION['username']);
}
if(isset($_POST['id'])) {
   $results = database_query("SELECT * FROM blah WHERE id = ?", Array($_POST['id']));
   $smarty->assign("results", $results);
}
$smarty->display("our_template.tpl");
?>

As should be apparent, the assign function is used to pass data to the template for display, and the 'display' function is used to select which template we wish to use. Because there is no output to the browser until 'display' is called, we can use any of the functions that output HTTP headers to the browser throughout nearly all of the file without getting the 'headers already sent' error.

In addition to the above you can find more useful resources below.

This is the tutorial that the above was taken from.
This resource is from the Smarty web site and is extremely useful.

As always if you have any questions on this post you can either leave a comment or contact me through Social Ajaxonomy.

PHP Ajax Chat Tutorial

Tagged:  

Jack Herrington has put together a starter tutorial for building a web-based chat application using PHP, MySQL, DHTML, Ajax, and the Prototype.js library. This by no means is a finished or polished application, but is intended to be a starter-kit for a chat application.

An interesting thing to note is that the tutorial does a good job of showing a potential pitfall of polling in Ajax applications. Polling can become a performance issue very quickly, especially if the amount of data returned by each request is ever increasing. The tutorial does provide a solution to help with performance along with all the required source code to build this starter application.

Suggestions the author has for extending this application are:

  • Track users: Put a list of the people actively engaged in the conversation alongside the chat. Doing so lets people know who is at the party and when they come and go.
  • Allow multiple conversations: Allow multiple conversations on different topics to go on simultaneously.
  • Allow emoticons: Translate character groupings such as :-) into the appropriate image of a smiley face.
  • Use URL parsing: Use regular expressions in the client-side JavaScript code to find URLs and turn them into hyperlinks.
  • Handle the Enter key: Instead of having an Add button, watch for users pressing the Enter or Return key by hooking onto the onkeydown event in the textarea.
  • Show when a user is typing: Alert the server when a user has started to type, so that other participants can see that a reply is pending. This lessens the perception that the conversation has died off to a minimum if you have slow typists.
  • Limit the size of a posted message: Another way to keep the conversation going is to keep messages small. Limit the maximum number of characters in the textarea —again by trapping onkeydown —to help speed up conversations.

Click here to check out the tutorial and download the source code.

Syndicate content