PHP

Aptana PHP Development Environment Released

Tagged:  

You may have used Aptana's IDE for Ajax development. The IDE is a very good one and it just got better for us PHP developers. Aptana has announced the release of a PHP plugin for their IDE.

Below is an excerpt from the announcement.

PHP development and deployment just got way easier. Today, we're pleased to announce the 1.0 availability of the Aptana PHP development environment. It's got all the things you'd expect from a PHP IDE, plus all the Ajax tooling and other power tools from Aptana Studio. Combine that with the integrated PHP app hosting, staging and management features in Aptana Cloud and you've got an end-to-end PHP development and deployment environment with unprecedented ease of use.

You can read the full post here.

It's always good to see one of my favorite languages get more support in tools that many of us already use. Thanks Aptana, you gave me something to play with this weekend.

Netbeans 6.5 Released

Tagged:  

In the tradition of "Release early, release often", the Netbeans team has released version 6.5, continuing the rapid release cycle the project set with 5.5, 6.0, and 6.1. There many new features, most notably support for Groovy /Grails and PHP. Here's a short list of the other "new and notables":

  • A new "Compile and Deploy on Save" feature for Java applications.
  • Support for the Nimbus look and feel in the Swing GUI builder (Matisse)
  • Big improvements in the JavaScript support, particularly in the area of debugging.
  • Support for Ruby on Rails 2.1 (JRuby 1.1.4 is bundled)
  • Improved SQL support, including SQL history and editor auto-completion.

There is also an early access release of Python support in Netbeans that is available as a separate download.

Get Netbeans 6.5 here.

Vista-like [not in a buggy way] JavaScript/PHP Datepicker

Tagged:  

Over at dev.base86, they've released version 2 of their Vista-like Ajax Calendar (vlaCalendar). The vlaCalendar is an unobtrusive JavaScript library that ports the UI functionality of the Windows Vista datepicker control to the web. The library requires the MooTools JavaScript framework as well as PHP.

In their own words:
Key features:

  • Authentic Vista look-and-feel
    • Quick navigation by jumping back and forth between months, years and decades without drop-down boxes
    • Smooth transition animations
  • Customizable features
  • Lightweight (compressed 8,50kB)

New features in version 2:

  • Cleaner and more developer centered - easily editable - CSS, PHP and javascript code
    • Easily changeable date labels (e.g. different languages)
    • Easily stylable. Styles are created on top of the general style; the download include two example styles
    • Both normal and datepicker calendar can be instantiated multiple times

The vlaCalendar has been tested on:

YouTube Data API Changes and Player API

If you haven't heard the big news yet, the YouTube Data API has been updated and the YouTube Player APIs have been released. The APIs look very interesting with some much wanted features.

The below is the big news from the YouTube Blog.

Here's the sound byte: We now support upload, other write operations, and internationalized standard feeds. (And there was much rejoicing!) We're also introducing player APIs and a chromeless player -- a barebones player SWF that's fully customizable and controllable using the player APIs.

The Data API now allows for reading (nothing new), writing and uploading of data (the latter two are the big news). The API allows for you to do many things that can be done in YouTube, such as add comments about a video or upload videos to YouTube. Libraries for the API are available for Java and PHP (sorry Ruby developers at least for now).

You can read more about the Data API here.

The Player APIs now offer a Flash (Actionscript 2.0) API and a JavaScript API to allow more control over the player. The JavaScript API and Flash API are very similar (which makes since as they are both based on ECMA Script). The APIs have some very powerful hooks into the videos. My personal favorite hook is player.getPlayerState() which returns the state of the player. Possible values are unstarted (-1), ended (0), playing (1), paused (2), buffering (3), video cued (5).

You can read about the JavaScript API here and the Flash API here (note that the Flash API is almost exactly the same as the JavaScript API, so you will need to read both references if you are going to use the Flash API).

Perhaps Even bigger news is the release of the chromeless player. Below is an excerpt about the chromeless player from reference.

Getting Started

First off, you need a developer key. To register for one, visit the registration page.

The chromeless player consists of two SWF files. apiplayer.SWF contains the actual video playing functionality. cl.SWF is a loader SWF that loads apiplayer.SWF and exposes the player's API functions. It also provides security sandbox restrictions for the apiplayer.SWF, so loading SWFs cannot access elements inside the player directly.

The player can be controlled via two methods — by loading the SWF into another SWF (or Flash website, etc.), or by embedding it directly in an HTML page and using JavaScript to control the player. The JavaScript controls are identical to the embedded player's JavaScript API.

The URL to load the chromeless player SWF is:

http://gdata.youtube.com/apiplayer?key=DEV_KEY

Functions

The following operations are available in addition to the ones listed in the JavaScript API documentation.

loadVideoById(videoId:String, startSeconds:Number):Void
Load the specified video and starts playing the video. If startSeconds (number can be a float) is specified, the video will start from the closest keyframe to the specified time.
cueVideoById(videoId:String, startSeconds:Number):Void
Loads the specified video's thumbnail and prepares the player to play the video. The player does not request the FLV until playVideo() or seekTo() is called. startSeconds accepts a float/integer and specifies the time that the video should start playing from when playVideo() is called. If you specify startSeconds and then call seekTo(), the startSeconds is forgotten and the player plays from the time specified in the seekTo() call. When the video is cued and ready to play, the player will broadcast a video cued event (5).
setSize(width:Number, height:Number):Void
Sets the size of the chromeless player. This method should be used in favor of setting the width + height of the MovieClip directly. Note that this method does not constrain the proportions of the video player, so you will need to maintain a 4:3 aspect ratio. When embedding the player directly in HTML, the size is updated automatically to the Stage.width and Stage.height values, so there is no need to call setSize() when embedding the chromeless player directly into an HTML page. The default size of the SWF when loaded into another SWF is 320px by 240px.

You can read more about the new features at the YouTube API Blog.

I think that these new feature really make it possible to make some great mash-ups with YouTube. If you create a cool mash-up using some of the new features of the API or use the the Player APIs or use the chromeless player then I would love to hear about it (you can leave it in the comments or you can write a blog post about it using your free Ajaxonomy account.

Creating a Simple JavaScript Game Board

Over at the Web Cash blog they have posted two tutorials on Game development in JavaScript, Ajax and PHP. The first tutorial explains the concept and describes how to make a game board.

Below is an excerpt from the first tutorial.

Game Development with JS, AJAX, and PHP

How can we use JS and PHP - connected through AJAX - to develop an online game?

Javascript’s main use for us is to create an interface for the game. Through Javascript we can capture user input - i.e. mouse clicks and text. We can also alter the game’s output - changing the HTML of the page, adding images, and moving things around. Javascript will provide a lot of the front end work.

PHP, on the other hand, is a more robust language for dealing with the logic of the game. PHP could be useful for developing an AI and evaluating winning conditions. It also offers a great way to store information for later use through flat files or database integration.

If we’re going to use both Javascript and PHP, we’ll need to use AJAX. This is the glue that holds the whole thing together. It will send input from the main Javascript to the PHP processing scripts. The PHP script will then send info back to the Javascript and it will alter the page’s layout accordingly.

Read the full first tutorial here.

The second tutorial goes into more detail as to how you would start creating a simple game. By the end of the tutorial you have a complete simple tic-tac-toe game (the game needs more logic added to be finished, but the concept is there).

Below is an excerpt from the second tutorial.

Creating Graphics

Tic Tac Toe Circle ImageI created two images in Inkscape to use for this board. Each is a 50×50 png file - with a gray background and a black border. The actual token (the circle or cross) is red and laid on top of the gray background.

Tic Tac Toe Cross ImageI’m no great artist, but these should work for a functional demo. We can worry about making nice circle and cross tokens later. I think getting the game working is more important than making it pretty from the get-go.

Turning Our .js Script into a Class

In making this a functional board, I also converted the script into an actual class. The script may end up being somewhat large and unwieldy - and an object oriented approach may help us keep it tidy and clean. Or it may add a lot of overhead… but I like objects.

In our HTML file, we’ll create the object like this.

<script type="text/javascript">
var tictactoe = new game();
</script>

In the attached .js file, we actually define the game object. Here’s part of the object definition.

function game() {
  //  Array to hold the bgImgs
  this.bgImgs = new Array();
    this.bgImgs[0] = 'tttcircle.png';
    this.bgImgs[1] = 'tttcross.png';

 
  //  Player information			
  this.currentPlayer = 0;
  this.players = new Array();
    this.players[0] = "Player One";
    this.players[1] = "Player Two";

 
   return true;

This class constructor does some of the initialization for us.

First, it creates an array with background images. At the moment we’re only using two images. However, this technique would be useful if you had a more complex map - with 10-15 images you could lay over a div.

Second, we create some player information variables. The ‘currentPlayer’ property is going to track whether the ‘cross’ or ‘circle’ player is currently taking a turn. The ‘players’ array will just hold the names of those players for now.

The Background Image Changing Function

One of the major methods of this class will be changeBackground(). Just like in the previous example, this method will change the background style of a given div tag. This way we can change it from an open square to a circle or cross token.

  this.changeBackground = function (boxId) {
    var box = document.getElementById('box-' + boxId);
    box.style.background = 'transparent url(' + 
      this.bgImgs[this.currentPlayer] + ') top left no-repeat';

 
    box.removeAttribute('onClick');
 
    this.changePlayer();
  }

This should be pretty straightforward. We’re storing the ‘div’ element in the ‘box’ variable. We’re then setting the ‘background’ style as we would in a css style. Remember that we stored the background images in an array (this.bgImgs) and this.currentPlayer corresponds to a key in the this.bgImgs array (either 0 or 1).

The ‘box.removeAttribute()’ method is removing ‘onClick’ from that div. We can’t use a square a second time, so we might as well eliminate the onClick handler altogether.

Finally, this.changePlayer() is calling a new method. This is going to help us switch from Player One’s turn to Player Two’s turn.

One Turn to Another - this.changePlayer()

The last method we need to declare for this class at the moment is changePlayer.

This will toggle the active player - which in turn affects whether a circle or cross is placed on the board. For some added effect, we’ll also create a new html element to display a message that says who’s turn it is.

  this.changePlayer = function () {
    //  Switch the active player

    if (this.currentPlayer == 0) {
      this.currentPlayer = 1;
    } else {

      this.currentPlayer = 0;
    }
 
    //  Get a reference to our 'message' element and create the message
    var box = document.getElementById('message');
    var msg = "It is " + this.players[this.currentPlayer] + "'s turn.";
    var txt = document.createTextNode(msg);

 
    //  Erase any existing text
    while (box.hasChildNodes()) {
      box.removeChild(box.lastChild);
    }

 
    //  Add the text node (our message) to our element
    box.appendChild(txt);
  }

Again, this is pretty straightforward. The DOM functions are amazingly simple - once you see how they work.

‘box’ is a reference to our element (id = message). The msg variable is a temp variable I created to hold the string. The ‘createTextNode’ method creates a new block of text (with our msg) that we can then insert into an HTML element.

The while() loop is simply there to erase any old text. As long as our ‘box’ element has any child nodes inside of it (text or other HTML tags), the loop will execute and delete one of those child nodes each time. This way we have a clean slate on which to write down who’s turn it is.

Read the full second tutorial here.

Although the tutorial only shows a simplistic tic-tac-toe game you could use the concepts as a starting point to build your own web games. As always if you have made any cool games we would love to hear about them either in the comments or you can write a blog post about it using your free Ajaxonomy account.

Simple AJAX chat in PHP

Tagged:  

Over at the .NET Butchering (and JAVA messes) blog they have posted a very good tutorial on creating a Chat application in PHP using Ajax. In Web 2.0 social applications chat is very often a desired feature.

Below is an excerpt from the tutorial.

The first thing to be done is creating MySQL tables:



CREATE TABLE `db_name`.`chat_rooms` (

`id` int(10) unsigned NOT NULL auto_increment,

`name` varchar(45) NOT NULL,

`description` text NOT NULL,

`table_name` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;



CREATE TABLE `db_name`.`roomX` (

`id` int(10) unsigned NOT NULL auto_increment,

`date` datetime NOT NULL,

`message` text NOT NULL,

`user` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

The first table, chat_rooms, contains a list of all available chat rooms, used to know wich table name will be used for each room. The second one, roomX is a template for a "chat room-like" table: it contains the date (date+time) of each message, the message itself and the user that inputed it (actually it should be an integer, that refers to an appropriate users table, but this is simple version of the script without logging features).

The first thing we're gonna do is execute those SQL scripts (we will be using MySQL and PHP native methods) replacing "roomX" with i.e. "friends_table", and after that we're going to populate the first table, to add an available chat room:



INSERT INTO chat_rooms(name,description,table_name)

VALUES("Friends chat","Comment...","friends_table");

The next step is to compose the "web application". Let's see this picture:

We will use a main page, chat.php, a dinamically reloaded page, room.php and a simple iframe with inside the page sender.php with some controls to post a message.

Let's see chat.php, removing all HTML stuff (like header and formatting, that's up to you):



<?php

session_start();

/* probabily login stuff */

$_SESSION['chat_time'] = $date;

?>

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

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

<script language="javascript">

var chatRoomId=<?=$charRoomChoosen?>;

</script>

<body onload="InitializeTimer(); StartTheTimer();">

<div id="chatText" style="overflow:auto;"></div>

<iframe src="sender.php" name="msgFrame"></iframe>

</body>

We'll talk further about the session variable chat_time; I've added 2 javascript scripts: the first one is a simple timer, the second one contains some methods to make HTTP requests.
This is httpRequest.js:



var xmlHttp;



function loadURL()

{

xmlHttp=GetXmlHttpObject()

if (xmlHttp==null)

{

alert ("Browser does not support HTTP Request")

return

}

var url="room.php?chatRoomId="+charRoomId;

xmlHttp.onreadystatechange=stateChanged;

xmlHttp.open("GET",url,true);

xmlHttp.send(null)

}



function stateChanged()

{

if (xmlHttp.readyState==4 xmlHttp.readyState=="complete")

{

/* trim message */

var newlines = xmlHttp.responseText.replace(/^\s+\s+$/g,"");

if(newlines!='')

{

var html = document.getElementById("chatText").innerHTML;

document.getElementById("chatText").innerHTML = html + newlines;

document.getElementById("chatText").scrollTop=20000000;

}



}

}



function GetXmlHttpObject()

{

var xmlHttp=null;

try

{

// Firefox, Opera 8.0+, Safari

xmlHttp=new XMLHttpRequest();

}

catch (e)

{

//Internet Explorer

try

{xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");}

catch (e){xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}

}

return xmlHttp;

}

This class does an HTTP request (using Firefox, Explorer and other browser Request objects), as I explained in the [Javascript]XML Loading post, and writes the result inside the DIV with id chatText, calling the room.php script (that actually outputs last message sent to the room). The charRoomId used as a parameter of the calling method, is a global variable defined in the chat.php header using a PHP variabile (it should be a $_REQUEST variable).

As we are using asyncronous calls, we need a component that recalls this request periodically. This is the code below (timer.js):



var secs;

var timerID = null;

var timerRunning = false;

var delay = 500;



function InitializeTimer()

{

// Set the length of the timer, in seconds

secs = 1;

StopTheClock();

StartTheTimer();

}



function StopTheClock()

{

if(timerRunning)

clearTimeout(timerID);

timerRunning = false;

}



function StartTheTimer()

{

if (secs==0)

{

StopTheClock();

// Here's where you put something useful that's

// supposed to happen after the allotted time.

// For example, you could display a message:

loadURL();

secs = 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

else

{

self.status = secs;

secs = secs - 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

}

This is a timer, called from the chat.php page with onLoad method, that recalls each delay milliseconds the function loadURL() function, defined inside the previous js file.

Now let's see what is inside the chat.php file:



<?php



/* **************** SESSION VARIABLES **************************** */

session_start();



if(!isset($_SESSION['chat_time']))

{

$_SESSION['chat_time'] = date("Y-m-d H:i:s");

$_SESSION['chat_time_delete'] = time();

}





/************** DB connection ********************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********** RETRIEVES THE NAME OF THE CHAT ROOM TABLE NAME **********/

function getChatTableName($connection,$chatRoomId)

{

/* recupera il nome della tabella della chat room */

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}



/******************* MESSAGE VISUALIZATION ********************************/





$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selection char room.";

exit();

}

$login_date = $_SESSION['chat_time'];



/* load messages */

$query = "SELECT c.message, c.date, c.user FROM ".$tableName." c WHERE c.date > '".$login_date

."' ORDER BY c.date ASC ";

$result = mysql_query($query,$connection);



$last = "";

while($row=mysql_fetch_array($result))

{

$message = html_entity_decode($row['message']);

echo "[".$row['user']."][".$row['date']."] ".$message." <br/>";

$_SESSION['chat_time'] = $row['date'];

}



/* delete messages older that 60 seconds*/

if((time()-$_SESSION['chat_time_delete'])>60 )

{

$query = "DELETE FROM ".$tableName." WHERE (NOW()-date)>60";

mysql_query($query,$connection);

$_SESSION['chat_time_delete']=time();

}



mysql_close($connection);

?>

We can see session variables initialization: chat_time is the time in which you entered the chat room or of the last message received, while chat_time_delete is the time in which you last deleted a message.
The scripts work this way:

  • connect to the database
  • retrieve the chat room table name using the chatRoomId request variable and the getChatTableName() function
  • query the DB searching for messages not yet received (basing unpon the time of last message received, and at the end of the loop we have a new value for chat_time, that is the last received message time
  • (because) once received messages are useless (a user after connection never received messages of the past), the script delete messages older than 60 seconds

Of course you can format as you like the message board.

At the end we find the sender.php page, that is wrapped in an HTML iframe (because every submission must not cause the entire page reload):



<?php



/***************+ DB variables *****************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********************* NOME TABDELLA CHAT ROOM **************************+*/

function getChatTableName($connection,$chatRoomId)

{

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}





if($_POST['action']=="send")

if($_SESSION['userid']!="")

{

$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selecting chat room.";

exit();

}



$query = "INSERT INTO ".$tableName."(user,message,date) VALUES(\""

.$_POST['userid']."\",\""

.htmlentities(htmlspecialchars($_POST['message']))."\",NOW())";



mysql_query($query,$connection);



}

?>



<body onload="document.msgForm.message.focus();">



<form name="msgForm" action="sender.php" method="post">

<input type="hidden" value="send" name="action"/>

<input type="hidden" value="1" name="chatRoomId"/>

<input type="text" name="userid" value="<?=($_POST['userid']=="")?"guest":$_POST['userid']?>" size="10" />

<input type="text" name="message" style="width:400px" maxlength="1500"/>

<input type="submit" value="invia"/>

</form>

</body>



<?php

mysql_close($connection);

?>

This page simply prints out a web form (in which users insert their nick name -in this version without a check- and the message) and -consequently to the submission- insert the message in the DB, that will be outputted by the timer.js routine.

This will be your final result:

You can read the full tutorial here.

Hopefully this tutorial will be useful to you.

Multi-player Ajax Games

Today I came across an interesting article about creating multi-player video games using Ajax. The article mainly deals with how you would send data to and from the server and also touches on keeping the game in sync on multiple clients.

The below code is how the post purposes that you would send data to the server side (this code uses a hand rolled Ajax call, but you could change it to use a library).

var httpSend = null;
var httpGet = null;

function send(action)
{
httpSend=GetXmlHttpObject();
if (httpSend==null){alert (?Your browser does not support AJAX!?);return;}

var url=?send.php?;
url=url+??action=?+action;
url=url+?&p=?+player;
url=url+?&g=?+gameid;
url=url+?&sid=?+Math.random();
httpSend.onreadystatechange=stateSend;
httpSend.open(?GET?,url,true);
httpSend.send(null);
}

function get()
{
if(httpGet != null) { return 0; }

httpGet=GetXmlHttpObject();
if (httpGet==null){alert (?Your browser does not support AJAX!?);return;}

var url=?get.php?;
url=url+??sid=?+Math.random();
url=url+?&p=?+player;
url=url+?&g=?+gameid;
httpGet.onreadystatechange=stateGet;
httpGet.open(?GET?,url,true);

httpGet.send(null);
}

function stateSend() {
if (httpSend.readyState==4){}
}

function stateGet() {
if (httpGet.readyState==4)
{
str = httpGet.responseText;
if(str != ?){
eval(str);
}
httpGet = null;
}
}

function GetXmlHttpObject() {
var xmlHttp=null;
try {
xmlHttp=new XMLHttpRequest();
}
catch (e) {
try {
xmlHttp=new ActiveXObject(?Msxml2.XMLHTTP?);
}
catch (e) {
xmlHttp=new ActiveXObject(?Microsoft.XMLHTTP?);
}
}
return xmlHttp;
}

The following code would be on the server side to receive messages. In the case of this example the code is PHP and the file is called Get.php

<?php
include(?config.php?);
$p = $_GET[?p’];
$g = $_GET[?g’];
$action = ?;
$query = mysql_query(?SELECT * FROM actions WHERE id = ?.$g);
$row = mysql_fetch_array($query);
$action = $row[$p];
$action = stripslashes($action);
$str = ?update actions set `?.$p.?` = ? where id = ?.$g;
mysql_query($str);
echo $action;
?>

The following code would be on the server side to send messages. In the case of this example the code is PHP and the file is called Send.php

<?php
include(?config.php?);
$p = $_GET[?p’];
$g = $_GET[?g’];
if($p == 1)
{
$b = 2;
}
elseif($p == 2)
{
$b = 1;
}
$action = $_GET[?action?];
$action = addslashes($action);
$query1 = mysql_query(?select * from actions where id = ?.$g);
$row = mysql_fetch_array($query1);
$str = $row[$b];
$str = $str . $action;
$str = ?UPDATE actions SET `?.$b.?` = ??.$str.?? where id = ?.$g;
$query = mysql_query($str);
if(!$query)
{
echo mysql_error().$str;
}
else
{
echo 0;
}
?>

You can read the full post here

The post also touches on the possibility of sending data via a text string. I personally think that for multi-player games JSON is a perfect data transfer method. Unlike XML there is not a large overhead and unlike sending data via a text string there is no parsing needed on the client which should help performance. This post is interesting as I think that Ajax can be a very useful method of transferring data for multi-player games.

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

Snipplr - a public source code repository

Snipplr is a public source code repository that gives you a place to store and organize all the little pieces of code that you use each day and It lets you share your code snippets with other coders and designers.

Snipplr was designed by Sitening, a Nashville Web Design company originally to store their code snippets in one place. They currently have around 3605 snippets in the following categories:
* ActionScript
* ActionScript 3
* Apache
* AppleScript
* ASP
* Assembler
* Bash
* C#
* C++
* Cold Fusion
* CSS
* Diff
* Emacs Lisp
* eZ Publish
* Forth
* Fortran
* Groovy
* HTML
* Java
* JavaScript
* Lisp
* Lua
* MatLab
* NewtonScript
* Objective C
* Open Firmware
* Other
* Pascal
* Perl
* PHP
* PicBasic
* Python
* Rails
* Regular Expression
* Ruby
* SmallTalk
* Smarty
* SML
* SQL
* SVN
* TCL
* TYPO3
* VB.NET
* VHDL
* Visual Basic
* W-Language
* XML

Click here to visit to the Snipplr code repository and let us know what you think.

Syndicate content