Archive for the 'PHP' Category

New Webthumb feature, Easythumb

Wednesday, November 29th, 2006

Updated
WebThumb added a new feature this week called Easythumb. Like the rest of webthumb its still in beta but it makes adding thumbnails too a site much easier.

Easythumb gives you a simple interface to WebThumb letting people with minimal PHP skills integrate WebThumb into there site. It does have a couple drawbacks, thumbnails are always cached (if someone else requested that same url within 24 hours then you get that thumb instead of making a new request), the output sizes are smaller, and some other options won’t be available.

Easythumb lets you generate a thumbnail using an normal http GET call, letting you put the request right in an img src. Easythumb thumbs are always cached, the default cache is 1 day, you can also use a 7 day and 30 day cache.

If a thumbnail is served from the cache it only use 1/5 of a credit
If the thumbnail is generated it uses 1 credit like normal

Note that currently Easythumb only generates thumbnails of sizes small, medium, and medium2

I have a small example script that shows Easythumbs usage it uses a little JavaScript trick to add a loading message. To use it on your site you just need to register a webthumb account. Copy this sample where you want it and update the parameters.


< ?php
// configuration parameters
$url = 'http://bluga.net/webthumb'; // make a thumbnail of this url
$apikey = 'your api key here';
$userId = 1; // your user id here
$date = gmdate('Ymd');
$size = 'medium';
$cache = 1;
$messageId = "tmessage1";

$parameters = "user=$userId&url=".urlencode($url)."&hash=".md5($date.$url.$apikey)."&size=$size&cache=$cache";
?>
<html>
<head>
        <title>Easy Thumb Sample</title>

<style type="text/css">
.thumbnail {
        position: relative;
}
.thumbnailMessage {
        position: absolute;
        top: 0;
        left: 0;
        width: 160px;
        height: 120px;
        background: gray;
        text-align: center;
}
</style>
</head>
<body>

<div class="thumbnail">
<img src="http://webthumb.bluga.net/easythumb.php?<?php echo $parameters; ?/>"
        title="Generated Thumbnail" width=160 height=120
        onload="document.getElementById('< ?php echo $messageId; ?>').style.display = 'none'"
>
<div class="thumbnailMessage" id="<?php echo $messageId; ?>">
Your thumbnail is being generated please wait
</div>
</div>

</body>
</html>

jQuery Slides are now available

Wednesday, November 29th, 2006

My slides from last nights azPHP presentation are now available. Feel free to post a comment if you have any questions.

Jquery at AZPhp Tomorrow

Monday, November 27th, 2006

I’ll be giving a talk about Jquery at the azPHP meeting tomorrow. If your in the Phoenix area you should come to the meeting, its at Walt Tv in Tempe at 7pm. azPHP meetings are a great place to meet fellow PHP developers and this month to learn some neat AJAX tricks.

Writing again

Wednesday, November 15th, 2006

I started writing the HTML_AJAX manual tonight, I didn’t get that far but it felt good to be at it again.

Anyhow this writing is more public (and hopefully a lot shorted) then my last project so anyone who is interested can take a gander right now. Its over on the HTML_AJAX wiki. I haven’t done any editing yet so feel free to fix anything I mispelled.

Oh and the first couple sections are just about AJAX in general, so the 60 second read might interest you even if you don’t use HTM_AJAX.

Great WebThumb article on Zend Developer Zone

Tuesday, October 17th, 2006

Cal Evans over at the Zend Developer Zone has written a very nice PHP5 wrapper and article about WebThumb. Read it for details and to get the code.

Oh and the WebThumb contest will be running until November 30th, all you have to do to win a free WebThumb account is to make something cool with WebThumb and release the code under a Open Source license. I’ll have more details and an official page up about it latter in the week.

New tutorial using HTML_AJAX and PEAR::Pager

Wednesday, October 4th, 2006

Lorenzo Alberton wrote a nice tutorial combining PEAR::Pager and HTML_AJAX. Its amazing how easy things get when you have some good libraries to rely on.

Webthumb API additions

Monday, October 2nd, 2006

If you wondered an API that requires polling isn’t a very good thing for scalability. On my current setup I can pretty easily handle about 20 status requests per second on top of my normal traffic, the problem is its not hard for a bad polling implmentation being run by one user to make that many requests.

To solve this problem im adding an addition to the Webthumb API that will allow you to skip polling all together. The basic idea is that your make an API request and when your thumbnail is complete i’ll make a GET request back too your server telling you that the request is complete.

So on the request side its just a matter of including an notify tag in your request block. An example is shown below:

<webthumb>
	<apikey>apikeyhere</apikey>
	<request>
		<url>webthumb.bluga.net</url>
                <notify>http://webthumb.bluga.net/sample/notify.php?secret=blahblahblah</notify>
	</request>
</webthumb>

I’m including a secret variable in the URL so that if someone found the URL of my notify script they couldn’t DOS me by making me download 100’s of different thumbnails from the server.

I’ve written a basic notify script to get you started. Feel free to use this script as a basis for whatever you need.

Update: Paths to thumbnails have changed so the download code listed here wont’ work. The new directory hash is:

<?php
substr($id,-2).'/'.substr($id,-4,-2).'/'.substr($id,-6,-4)
?>

Which means if your job id is: wt4761c8f914559 then the directory is: http://webthumb.bluga.net/data/59/45/91/

<?php

// this is a really simple notify script
// it downloads the specified thumbs for a job and puts them in the storage dir
// if you want to store files based urls etc you'll need to store the id at request time
// then do a mapping in this script

// download options
// zip     - all sizes in a zip
// zipAuto - zip download and auto uncompress
// large   - 640x480
// medium2 - 320x240
// medium  - 160x120
// small   - 80x60
$downloadType = 'zipAuto';

// secret id im using to make sure no one has me download every thumb etc
$mysecret = 'changeme';

// directory to write files too
$storageDir = 'tmp';

// webthumb base url
$url = 'http://webthumb.bluga.net/data/';

// unzip command
$unzipCommand = 'unzip';

// END CONFIG
if (!isset($_GET['id']) || !isset($_GET['secret'])) {
    exit;
}

if ($mysecret == 'changeme') {
    echo "Configure notify script";
    exit;
}

$jobId = $_GET['id'];
$secret = $_GET['secret'];

if ($secret !== $mysecret) {
    echo "bad secret";
    exit;
}

$jobDir = substr($jobId,-4);

switch($downloadType) {
    case 'zip':
    case 'zipAuto':
        $file = "$jobId.zip";
        break;
    default:
        $file = "$jobId-thumb_$downloadType.jpg";
        break;
}

// this is the simplest possible download code, curl, PEAR http_request might be better
// will only work if allow_url_fopen is on
$contents = file_get_contents($url.$jobDir."/$file");
file_put_contents($storageDir."/$file",$contents);

if ($downloadType == 'zipAuto') {
    exec("cd $storageDir && $unzipCommand $file");
    unlink($storageDir."/$file");
}

?>

Let me know if you find any major bugs in the code. There are always going to be cases where the polling API makes more sense (command line utils etc) but I think this notify API should work great for any application integration.

I’ll be speaking at php/works

Wednesday, September 6th, 2006

Due too a last minute change i’ll be at php/works on Wednesday.

I’ll be giving two AJAX sessions:
Scaling with AJAX
JavaScript Light & Sweet

I’ll be following the original synopsis for the sessions, but since I haven’t started preparing there might be some slight changes.

Since it was so last minute I won’t be at the entire conference I’m flying into Toronto on tuesday and returning to Phoenix wednesday night, but hopefully I’ll still have a chance to put a face too a lot of PHP developers i’ve only met online.

PHP Webthumb API wrapper

Monday, September 4th, 2006

Over the weekend Hansin wrote a PHP Webthumb API wrapper and released in under open source. Webthumb seems to be handling the load pretty well, its already generated 2600+ thumbnails today.

So if you want an easy way to generate webpage thumbnails right from your PHP applications now you have one.

I’ll be looking at some various rate limits and queue adjustments over the next week to keep one user from clogging up the queue too much. Until then be nice, and enjoy.

Webthumb API released

Friday, September 1st, 2006

Webthumb now has an API. Its a simple REST API based on posting some simple XML.

It gives you the ability to request thumbnails, check on there status, and even download files.

To use the API register and then goto your user page, your API key is shown there.

Basic docs on the Webthumb API are available.

If you have any comments or suggestions leave them as comments.

The API is currently in beta so im sure there will be some changes and additions, but its a very usable state. If someone wraps the API for easy PHP access i’d be interested in hosting the code so if you write a wrapper please get in touch with me.

HTML_AJAX reaches beta

Wednesday, August 30th, 2006

Yesterday we released HTML_AJAX 0.5.0

It contains lots of bug fixes and a couple new features, but the biggest change is this means were commiting to a stable API. Between this release and 1.0 will be in a feature freeze, focusing on improving documentation and fixing any problems.

You can upgrade by running pear upgrade HTML_AJAX-beta

Webthumb adds login and quick submit

Tuesday, August 29th, 2006

I’ve upgraded webthumb, adding in login support and given logged in users the ability to quickly submit multiple webthumb requests. Logged in users also have a recent thumb bar on their user page, and will be getting more historical features over time.

I’m also getting close on the API front, in reality its really already there, since you can submit requests using AJAX. Mainly I need to figure out a general authorization plan, and get a the code exposed in a formal way.

To check out the new webthumb features register and then login and visit the user page.

Also also still trying to figure out what the terms of service will be on the API. I’m currently thinking about 200 thumbnails free and then $.05 per thumbnail after that. I will be rolling things out for testing purposes without any commercial options, but your feedback would be appreciated if your interested in generating a large # of thumbnails.

Update

This came up in the comments, and I responded there, but i think it makes sense to update the post as well.
AWS sells thumbnails are a much cheaper rate. My reasons for the higher rate are:

  • Thumbs of sites how it looks today
  • More thumbnail sizes
  • Thumbnails from any url

What sort of premium do people think thats worth, or are these mainly the type of features people want for low use activities.

AJAX Answers

Thursday, August 17th, 2006

The last couple days have been a lot of fun. I was at LinuxWorld and did a book signing yesterday, my publisher had the first copies of Understanding AJAX at their booth. They should be showing up at bookstores and Amazon in the next couple weeks.

Your AJAX answers from my AJAX questions post are below, I hope everyone finds them helpful.

Dealing with broken connections

Question:

How can I find out whether a connection is broken? Should I just set a unique timeout per request after which an error message can be displayed? The timeout would be deactivated if the AJAX call succeeds. Is this a smart idea and does it work?

Answer:

Using a timeout per request does work though its not a perfect solution. HTML_AJAX uses this approach, and a default timeout of 20 seconds. The issue is that 20 seconds is a long time to wait to provide an error, but there are still cases that hit this value. Its also hard to know what to do if you’ve hit an error, is this a transient failure and you should resend your request, or can you know longer talk to the server and you’re app needs to provide and error.

HTML_AJAX vs Prototype

Question:

Why would you want to use HTML_AJAX when there are far better tools for the job, pure javascript solutions such as prototype or jquery? I don’t think you need something special on the serverside to return some data as a response to an AJAX call.

Answer:

I guess you don’t like HTML_AJAX, which is ok, but there are lots of reasons why developers want AJAX libraries that are closely tied to there server side language. Libraries like HTML_AJAX make it easy to perform RPC style AJAX, and they usually make it possible to write less JavaScript on just focus on your primary server side language. Though these libraries do this to varying degrees of success. Something like SAJAX just handles the RPC, while HTML_AJAX can be used with very limited JavaScript writing (HTML_AJAX_Action stuff), and most of the .NET AJAX libraries allow you to add AJAX with no JavaScript at all, since the .NET code behind concept make its really easy to automatically chunk up your code.
Even if there is a JavaScript library you think its great, that doesn’t mean it offers the tools that everyone wants.

Degradable AJAX sites and JavaScript behaviors

Question:

What is the best way to ‘degrade’ a website when Javascript/XMLHttpRequest support is disabled? Take f.e. yahoo.com. It’s a great website enriched with AJAX, but when JS is disabled it’s still looks the same but the rich features are not there. Would you consider CSS-style selectors as the solution? I do not want to create two different websites, one JS enabled and the other JS disabled. Thank you in advance.

Answer:

CSS-style selectors, like those you use with the Behavior library gives you a good tool to write a degradable AJAX site, but the actual implementation can be pretty hard.

In general it means fully implementing a site without AJAX, then picking forms, links, etc that you want to make AJAX and tieing the AJAX too them at runtime. This works really well if your just doing something like type-ahead search since your not changing work flows, but it doesn’t always work that great for form submissions, since they often update different parts of the page, and the code that processes them is generally designed to build the whole page.

If your using AJAX for enhancements that don’t change the actual work flow then making your site degrable is easy. If your site relies on AJAX for its basic workflow you’ll have a much harder time making a site degrade.

Attaching JavaScript using css selectors is a great approach since it keeps your HTML completly seperate

Adding JavaScript on using AJAX

Question:

When utilizing an AJAX API such as Google Maps, how do you execute embedded Javascript commands in a page generated on-the-fly? For example, you have a website which contains several ’s, one of which is an implementation of the API (i.e. a Google map). That loads when the page loads. Now, based on user interaction (clicking on links), you pull an SQL result from a database and display 10 at a time in a separate . Each time the loads, you want to execute some commands through the AJAX API. In my understanding, JS only executes at the browser page load, but I’m sure I’ve seen sites that get around this.

Answer:

While its true that you can’t directly add JavaScript too a page using script tags and innerHTML, that doesn’t mean you can’t add JavaScript to your page at any time. The simplest way is too just send your new JavaScript as text and run it through eval too add it too the page. You can also parse your strings before adding them with innerHTML and run eval as nesseccary. HTML_AJAX provides a method for doing this parsing for HTML_AJAX_Util.setInnerHTML. If you use it JavaScript in any script tags will be run. Other libraries like prototype also offer similar features.

AJAX File Upload

Question:

how can i make a file upload via ajax?

Answer:

If you think of AJAX as involving using XMLHttpRequest then you can’t (at least not without disabling the browsers security model, which i don’t even recommend for intranet apps). But you can still upload files asyncronously, its just a matter of targeting a form at a hidden iframe. You will also want to look at generating your IFrame in JS since i believe it gives you less problems with browser history.


<iframe name="upload" id="upload"></iframe>
<form target="upload">
<input type="file"/>
</form>

AJAX Form Submission

Question:

I’ve been studying AJAX for a bout a month now but I have not yet grasped the tecnique to submit a form with POST method. I’ve been trying to find an article that covered that but all I could find was the ones that included somekind of already made framework.

I want to know how to submit data to server (like form or email sending) with POST method.

Answer:

Submit a POST request using AJAX you first have to understand what a normal form POST is.
When you submit a form in your browser it makes a http request with the following options:
HTTP Verb: POST
Content-Type: application/x-www-form-urlencoded
And a body of something like:
fielda=valuea&fieldb=valueb

So to replicate a form POST in AJAX you need to run xmlhttp.open with POST set a header, xmlhttp.setRequestHeader(’Content-type’,'application/x-www-form-urlencoded’);

Then encode your content and send it.
xmlhttp.send(’fielda=valuea&fieldb=valueb’);

If you use a library most have code for handling this for you, HTML_AJAX has HTML_AJAX.formSubmit for taking a form and submitting it using AJAX and HTML_AJAX.post for doing custom POSTs.

AJAX Question updates

Monday, August 14th, 2006

I’ll be answering your AJAX questions tomorrow, so if you have any thing else, head over to my last post and ask away.

Also I’ll be at Linux World tomorrow so if you’re taking part in the healthcare day make sure to stop by and take a look at Clearhealth.

Adding AJAX to a Website step by step, Part II

Thursday, August 10th, 2006
I have a lot more change's i'd like to make to webthumb so the last article (Adding AJAX to a website step by step) is now the start of the series. In this article will be taking front page of webthumb and making it live. The the stats and recent thumbnails will update in real time, making for a nice slick presentation. Webthumb Frontpage

I hope to release and article for each improvement I make to webthumb, giving everyone idea of whats involved in AJAXing a real website. But a series of articles won't cover everything you want to know about AJAX. If your interested in learning more you should take a look at my book, Understanding AJAX (should be shipping september 1st), it covers everything from basic AJAX implementations to usability and debugging.

Getting realtime data with AJAX

The frontpage of webthumb could be updated with each new thumbnail that is created. In straight HTML you might handle updating things by using a meta refresh. The problem with this, is your loading a lot of repetitive content, and the full page refresh makes for a clunkly look.

With AJAX you can poll the server on a regular interval and just update things when data has changed. Polling approaches can cause scalability problems since they can create a large number of requests to your server. Hopefully this won't be a problem in this case since i'll be making small requests and returning a large amount of data, and I don't need to make them that often. There is also an alternate approach that you can use called comet, that works by each client keeping a connection open to your server and pushing data to them. But a push approach brings about a whole new set of scaling problems, so will stick with tried and true polling, and i'll cover comet some time in the future.

Exporting the PHP Class

Like the last upgrade will be using HTML_AJAX for our AJAX communications. On the server side I created a new class called WebthumbStats, it has a single method named "updatesSince", that takes a timestamp as its parameter. If you were using it in php you'd get something that looks like:

<?php

$stats = new WebthumbStats();
$update = $stats->updatesSince($lastPoll);

?>

If nothing had changed since my last poll i'll get a timestamp back. If something has changed I'll get an array of data back containing the basics stats, a timestamp, and the new image ids. Will use the timestamps from the server when making the next poll request that way we don't have to worry about problems with the client's time settings messing things up. A result might look something like:

<?php

array(
  'queue' => 1,
  'lifetime' => 1324,
  'today' => 329,
  'time' => '2006-08-07 16:45:01',
  thumbs => array(
    array (
      'img' => '/webthumb/data/ba86/wt44dac13bcba86-thumb_medium.jpg',
      'url' => 'http://bluga.net',
    ),
    array (
      'img' => '/webthumb/data/46d6/wt44dac3c4546d6-thumb_medium.jpg',
      'url' => 'http://blog.joshuaeichorn.com',
    )
  )
);

?>

After writing the PHP class I wrote a small test script in PHP and made sure it was working right, then I registered it in ajax.php.

<?php

require_once 'HTML/AJAX/Server.php';

class WebthumbServer extends HTML_AJAX_Server {
        var $initMethods = true;

        function initRequestStatus() {
                require_once 'lib/RequestStatus.class.php';
                $this->ajax->registerClass(new RequestStatus(),'RequestStatus',array('getStatus'));
        }

        function initWebthumbStats() {
                require_once 'lib/WebthumbStats.class.php';
                $this->ajax->registerClass(new WebthumbStats(),'WebthumbStats',array('updatesSince'));
        }
}

$server = new WebthumbServer();

$server->handleRequest();

?>

You'll notice the basic registration is the same style as we used for RequestStatus but now its enclosed in a class. The init method functionality in HTML_AJAX_Server gives you a way to organize how the PHP class are setup for AJAX access. It also means that when a request is made to RequestStatus WebthumbStats code won't be loaded. With just two classes this doesn't save a ton of overhead, but every lit bit helps, and when you get too 20 or 30 AJAX classes it can make a huge difference.

Polling with HTML_AJAX

The JavaScript side is really simple. We poll on a set interval, with a check to make sure we aren't waiting on another poll to finish. Other then that its just a matter of getting a starting timestamp from the server when we generate the page. The polling code looks like:


HTML_AJAX.defaultServerUrl = 'ajax.php';
var inProgress = false;
var statsInterval;
var lastPoll = '< ?php echo $now; ?>';

function setupStats() {
        statusInterval = window.setInterval(statsUpdate,8000);
}
function statsUpdate() {
        if (inProgress) {
                return;
        }

        inProgress = true;

        HTML_AJAX.call('WebthumbStats','updatesSince',statsCallback,lastPoll);
}
function statsCallback(result) {
        inProgress = false;
        if (result.time) {
                // do something with updates here
                lastPoll = result.time;
        }
        else {
                lastPoll = result;
        }
}

Updating contents on new data

Lets start with updating the basic stats since thats the easy part. We just give the div containing each of the statistics an ID and then replace there innerHTML with the new content. This code looks looks like:


$('queue').innerHTML = result.queue;
$('lifetime').innerHTML = result.lifetime;
$('today').innerHTML = result.today;

Updating the thumbnails is a little harder since we want to add new thumbs on the left of the list and drop the old ones off the right. The thumbs array we have returned is shown oldest first, so we can just append to the begining of the list and delete from the end. Using a little getElementsByTagName, insertBefore and remove child lets us make the image updaes a reality.


                var images = $('recent').getElementsByTagName('div');

                for(var i = 0; i < result.thumbs.length; i++) {
                        var newImg = images[0].cloneNode(true);
                        newImg.getElementsByTagName('img')[0].src = result.thumbs[i].img;
                        newImg.getElementsByTagName('a')[0].href = 'pickup.php?id='+result.thumbs[i].id;
                        newImg.getElementsByTagName('a')[1].href = result.thumbs[i].url;
                        newImg.getElementsByTagName('a')[1].innerHTML = HTML_AJAX_Util.baseURL(result.thumbs[i].url.substring(7));

                        $('recent').insertBefore(newImg,images[0]);
                        $('recent').removeChild(images[4]);
                }

The line using HTML_AJAX_Util.baseURL is updating the domain below the image, were using baseURL just like you would use basename in PHP. This domain chopping keeps long urls from making the list look bad.

Using HTML_AJAX to manage JavaScript library delivery

HTML_AJAX delivers its JavaScript libraries through HTML_AJAX_Server. This code can also be used to deliver any other JavaScript library you want. Its main features are, setting headers for client side caching, and allowing you to easily combine multiple files together so clients don't have to open as many connections to your server.

To finish this update, I'm going to need moo.fx so my first task is too register it with my server.

<?php

$server->registerJsLibrary('moofx',array('prototype.lite.js','moo.fx.js'),'/home/htdocs/javascript/');

?>

This registration makes the keyword moofx delivery the prototype lite depenency and the moo.fx library. These files are grabbed from /home/htdocs/javascript on my server.

Then i just update my include to pull in moo.fx


<script type="text/javascript" src="ajax.php?client=html_ajax_lite,alias,moofx"></script>

Adding some Effects

The auto updating stats are neat, but the change is so subtle people might not notice its happening. To make it clear an AJAX update is happening I'll add a couple effects.

I'm going to animate the height down to zero on a thumbnail before I delete, and fade in the next text on my stats boxes.

To do a fade you create a new Opacity animation


var fadeIn = new fx.Opacity($('StatusBoxes'));

Then you call its custom method giving it the starting and ending opacity.


fadeIn.custom(.1,1);

The same approach is used to shrink the thumbnail out, only this time will set some options.


var shrink = new fx.Height(images[3],{duration:1000,onComplete:function()
                                {
                                        $('recent').removeChild(images[3]);
                                        $('recent').insertBefore(newImg,images[0]);
                                }
                        });
shrink.custom(160,0);

I use the onComplete event handler to remove the element when im done shrinking it and too add the new one.

Thats all for now

We covered a lot of ground in this article, some old some new. If you have any suggestions, or requests for further explanation please leave a comment.


Adding AJAX to a website step by step

Tuesday, August 8th, 2006

Update: The next article in this series is now complete.

Webthumb is a small project of mine that takes a snapshot of a website and gives you thumbnails in 4 different sizes. Currently the site is rather boring and has a couple of usability problems especially on the pickup page. Over the next couple of days I'll be using various AJAX techniques to upgrade Webthumb, writing about the process as things happen.

When looking at a adding AJAX you have a couple decisions you'll want to make up front. One is what tools your going to use. In the webthumb case thats pretty easy. Webthumb is a simple PHP app and doesn't use a framework, so I need a nice general PHP/AJAX framework that is easy to use, HTML_AJAX fits that need. I may also need so animations or other effects, since im not planning on doing anything really fancy i'll use the extremly small but powerful moo.fx. I'll also keep scriptaculous in mind if I end up needing something fancier, but I think its overkill for this project.

After picking my tools I need to decide what my goals are. My main focus will be to improve usability, but I also want to use AJAX to make the site seem a bit flashier, so its a bit of a technology demo too.

Updating Thumbnail Pickup

The first page im targeting is the thumbnail pickup page. Thumbnail generation is an asyncronous process, you make a request which is added to a queue and the thumbnail processor walks the queue generating thumbnails updating the status when its done. The current way this is handle is by letting the user reload the page a bunch of times, but the speed of thumbnail generation isn't consistent so if things run slow its easy to thing something is broken. I'll be fixing this by using AJAX to poll the server on a 1 or 2 second interval, and use that information to make some sort of a progress bar.

HTML_AJAX and PHP remoting

HTML_AJAX supports a number of different ways to add AJAX to your pages, in this case I've chosen to use its PHP remoting supporting. This works registering a PHP class to be used by JavaScript, and then using a proxy object from JavaScript to make calls or making calls with the classname and methodname specified. Since im only going to be making a few calls im not going to be using a proxy object, if you want some examples on how that works checkout my Hello World with HTML_AJAX post.

The RequestStatus PHP class

The class i'll be exporting too JavaScript is call RequestStatus it currently has a single method, getStatus. If you were using it in PHP a call would look something like:

<?php

$status = new RequestStatus();
$jobStatus = $status->getStatus($jobId);

// job is in queue
if ($jobStatus['status'] == 'queue') {
  echo 'Job is in Queue, there are '.$jobStatus['wait'].' jobs in front of it';
}
else if ($jobStatus['status'] == 'processing') {
  echo 'Job is being processed, it started at'.$jobStatus['start'];
}
else if ($jobStatus['status'] == 'complete') {
  echo 'Job is complete';
}

?>

Exporting a PHP Class

The easiest way to make a PHP class available to JavaScript is too use the HTML_AJAX_Server class. If your using a framework you can either integrate this class into your front controller to handle AJAX dispatch or you can use the HTML_AJAX class directly and write your own equivalent of HTML_AJAX_Server to handle call dispatch. I run HTML_AJAX_Server inside of a file called ajax.php, an example of which is shown below. The only item of note is that im specify the methods on that class to export, doing this is always a good idea, and its the only way to keep method case in php4.

<?php

require_once 'lib/RequestStatus.class.php';
require_once 'HTML/AJAX/Server.php';

$server = new HTML_AJAX_Server();

$server->registerClass(new RequestStatus(),'RequestStatus',array('getStatus'));

$server->handleRequest();

?>

At this point a good thing is test that the class has been registered correctly and isn't thowing any PHP errors. To do this load the generated JavaScript stub up in your browser, ajax.php?stub=RequestStatus. For any class the result should look something like below:


// Client stub for the RequestStatus PHP Class
function RequestStatus(callback) {
	mode = 'sync';
	if (callback) { mode = 'async'; }
	this.className = 'RequestStatus';
	this.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,'/webthumb/ajax.php?','JSON');
}
RequestStatus.prototype  = {
	Sync: function() { this.dispatcher.Sync(); },
	Async: function(callback) { this.dispatcher.Async(callback); },
	getStatus: function() { return this.dispatcher.doCall('getStatus',arguments); }
}

Making AJAX calls to RequestStatus

Now that the backend is setup its just a matter of making some AJAX calls on the thumbnail pickup page.

To do this we'll create a new JavaScript function will be run by the pages onload handler. It will start a timer that makes a call to getStatus every 2 seconds, as long as another request isn't currently being waited on. Will be using HTML_AJAX.call to make the requests.

To get the needed JavaScript libraries I specify a client parameter too ajax.php. Im grabbing all the default libraries and the optional alias library. Alias lets me type $('id) instead of document.getElementById.


<script type="text/javascript" src="ajax.php?client=all,alias"></script>

My status code check code is pretty simple, if the status is complete is reload the page, and let the PHP code display the images. If not I display a new status message, either the items ahead of this thumbnail job in the queue, or the time that processing started on the thumbnail. I also added a simple animated loading gif. The status check JavaScript is below, followed by the HTML it updates.


HTML_AJAX.defaultServerUrl = 'ajax.php';
var inProgress = false;
var jobId = '< ?php echo $jobId; ?>';
var statusInterval;

function setupStatusCheck() {
        statusInterval = window.setInterval(statusCheck,2000);
}
function statusCheck() {
        if (inProgress) {
                return;
        }

        inProgress = true;

        HTML_AJAX.call('RequestStatus','getStatus',statusCheckCallback,jobId);
}
function statusCheckCallback(result) {
        inProgress = false;

        if (result.status == 'complete') {
                window.clearInterval(statusInterval);
                window.location = '< ?php echo $_SERVER['PHP_SELF']; ?>?id='+jobId+'&reload=true';
        }
        else if (result.status == 'processing') {
                $('statusMessage').innerHTML = 'Thumbnail generation started at '+result.start;
        }
        else if (result.status == 'queue') {
                $('statusMessage').innerHTML = 'Your thumbnail is in the processing queue, there are '+result.wait+' items ahead of it';
        }
}

               <div id="statusBlock">
                        <p id="statusMessage">Your thumbnail is in the processing queue, there are < ?php echo $waiting; ?> items ahead of it.

This page will automatically update when the thumbnail is complete.

<img src="loading.gif"/>
                </div>

There are a number of other enhancements we could make to this page. First it could use some CSS cleanups to look nicer. You could also skip the last reload by adding the images using JavaScript. And finally I could make a nicer way to show the 4 thumbnails. These enhancements and some some fun project on the front page will be covered in future articles.

Oh and these changes are live, so you can check them out by visting webthumb and putting in a url.


Understanding AJAX Digital Shortcut Available

Thursday, August 3rd, 2006

A chapter from my book, Understanding AJAX has been made available as a digital shortcut. This chapter covers the different ways you can use the data you transfer using XMLHttpRequest.

Document centric approaches based on HTML and XML are described as well as various RPC approaches are shown.

Personally i tend to use JSON based RPC approaches or HTML document based approaches. Document based HTML approaches let you add AJAX support without radically changing your development model, since its just a matter of breaking your pages into small chunks and generating HTML just like normal. RPC approaches allow you to develop JavaScript driven apps, which is great for quick prototyping and small apps, since you can write a backend in PHP and have it made immediatly accessible (at least if you use a library like HTML_AJAX to do the work for you) to your HTML and JavaScript frontend.

In Clearhealth we use both approaches. JavaScript widgets like our patient selector make RPC requests. While screens like the claim editor make standard HTTP POSTs treating each form section like it is its own page.

I don’t do much work with AJAX and XML, but client side XSLT can be a good solution if you need to move lots of data since it tends to scale better to extremly large datasets (especially in IE).

If your interested in the details of these various approaches grab the digital shortcut or pickup Understanding AJAX.

phpDocumentor enhancements

Thursday, July 13th, 2006

As PHP keeps added language features one of the things we have to do is figure out how to document them.

Lately I’ve been hearing requests for a way to document virtual properties and methods on classes that are implemented using __call etc.

After talking a bit with Greg, I’m leaning towards adding in some new docblock tags to classes to allow these methods/properties to be documented.

It might look something like this:

<?php

/**
 * whatever
 *
 * @property int $blah this is the short desc (no long desc allowed)
 * @property-read int $foo read-only variable
 * @property-write string $oof write-only variable
 * @method int myfunc(int $var, string $param2, Object $param3 = null) description of myfunc
 */
class magicClass {
}

?>

My big concern with this approach is it can lead to a unwieldly class level docblock and it makes it hard to add large descriptions. On the plus side this is easy to implement and normally when you have a virtual method/property it doesn’t need a lot of description.

Finally if anyone has thoughts on managing changes like this in the future let me know. Right now we consider the phpDocumentor manual to be the official guide to how things work, but im not sure if that works that well for other people writing phpdoc parsers (ide’s etc).

Related Bugs:

HTML_AJAX Wordpress Plugin Tutorial

Monday, June 26th, 2006

I found a handy tutorial of building a stock lookup plugin for Wordpress using HTML_AJAX. Shows how easy HTML_AJAX makes AJAX.

The only problem I see is the code won’t work in PHP5 since introspection will return the method name as GetQuote instead of getquote.

You can fix this by adding the following to the HTML_AJAX_Server instance.

// Create the HTML_AJAX Server
$objServer = new HTML_AJAX_Server();

// Set php4 case compatability so this code will work in 4 or 5
$objServer->ajax->php4CompatCase = true;

The other option too fix this is too set all the methods you want to register which is my prefered fix since it lets you have nice case in your JavaScript functions in php4

    // Create the HTML_AJAX Server
    $objServer = new HTML_AJAX_Server();

    // Create an instance of our stock quote class
    $objStockLookup = new StockQuote();

    // Register the stock quote object with the HTML_AJAX server
    $objServer->registerClass($objStockLookup,'StockQuote','GetQuote');

If you did this you’ll also have to update the JavaScript to use the cased version of the functions.

HTML_AJAX 0.4.0 is released

Friday, April 7th, 2006

HTML_AJAX 0.4.0 has been released. You can upgrade using the PEAR package manager in the normal ways.

The biggest new feature is the addition of a setInnerHTML method that runs any JavaScript in the string your using to update and elements innerHTML property and the addition of an ordered queue. The ordered queue makes your AJAX requests return to the client in the same order they were sent. One of the biggest area’s this comes into play is when creating livesearch implementations or any other time you’re making lots of AJAX requests and overwriting the results of the earlier ones with the results of latter ones.

More details (including a place to put testing results for your browser of choice) are available in the release notes on the HTML_AJAX wiki.

I’d also like to thank Laurent Yaish for helping with the testing of this release and Arpad Ray for working with me until we got the optimal implementation of setInnerHTML.

This circle expands additional navigation
You should really buy my AJAX book.
You'll learn not only the technology you need for implementation but also an understanding that will help you get the most from AJAX.
You'll also have my eternal thanks :-)