Hacking Variable Composition: Another Approach to PHP Lambdas

I was fooling around with variable composition today and had a cool idea. Before that, if you don't know what variable composition is then here are some examples of the neat manipulations PHP lets you do with variables.


// variable variables
$foo = 'bar';
$bar = 'hello';

echo $$foo; // outputs: 'hello'

// variable composition
$foo = 'bar';

echo ${'foo'}; // outputs: 'bar'

Essentially it is just different syntax for variables. However, with the right techniques, we can make it into so much more. For example, here is a composed variable that will actually execute a database UPDATE query:

// fake db query
function db_query($sql) {
	// do query here...
	echo $sql;
}

function query_error_handler($error_num, $error_str, $error_file, $error_line) {
	if($error_num == 8 && preg_match("~^Undefined variable: update~i", $error_str)) {
		return db_query(str_ireplace('Undefined variable: ', '', $error_str));
	}
	return FALSE;
}

set_error_handler('query_error_handler');

// perform a db query
!${"UPDATE mytable SET foo='bar'"};

You should be able to determine just from looking at this that you shouldn't use this type of hack in production code. Otherwise, for the curious programmer, it's definitely an interesting line to pursue. Now, on to Lambdas. My last article on closures/lambdas fixed a few bugs in my system and cleaned up the code; however, there was still the annoying of having to used ->call() to call the function. Essentially, I want to be able to do: lambda(...)(arg1[, arg1[, arg3[, ....]]]). Unfortunately this cannot be done. However, it can be approximated with variable composition. Check this out:

$lambda_1;

function lambda($args = '', $content = '') {
	
	global $lambda_1;
	
	$lambda_1 = create_function($args, $content);
	
	return 'lambda_1';
}

echo ${lambda('$a', 'return $a;')}('hello world');

// output: 'hello world'

Clearly this code was set up specifically for this example, however I definitely think that this can be built on.

Don't Use __autoload Directly

I've been working on my framework over the weekend and drafting a concept for a mini application that I will do in my free time (if I finish the concept and like it). The concept has to do with two previous posts; essentially I am fufilling a promise in one of those two posts! But otherwise...

PHP's __autoload function is a great little helper function if you're coding in an object-oriented environment. It automates those dreadful PHP4 autoload-like functions by removing the use of calling a function to make sure a class is loaded/exists. Unfortunately __autoload lacks scope/namespace. What do I mean?

If we are working on a script and we are using third party code and both code bases define an __autoload function then we will encounter a serious problem! The options: either go into their code and recode it, remove their autoloader (not a viable option, they could be dependent on it), or write our own custom handler and do everything the PHP4 way. Guess what the best option is? Surprisingly enough, it's both the first and last one together.

Here's the solution: rename their __autoload function to anything else, create your own custom autoload function that would act as if it were the __autoload function, and then add both to the default autload stack.

function my_autoload($class_name = '') {
    // moo
}

spl_autoload_register('my_autoload');

That was simple. The spl_autoload functions are only supported in PHP versions greater than or equal to 5.1.2. This means that if you are using an earlier version, you can easily replicate these functions by creating an __autoload() function which taps into a singleton stack that your custom spl_autoload functions modify.

Hope this makes people more aware of the realities of using others code and taking advantage of some of the more apparent than real panaceas that PHP offers.

A quick note to anyone who didn't realize this, but if the second parameter of class_exists is not set to FALSE, then __autoload will be called if it's defined.

Taking Advantage of Exceptions in PHP5

If you've never used PHP5 exceptions then it's time to start. They are a great way of handling specific types of errors uniformly and allow you to handle/fix/bypass problems that could otherwise cripple your script.

An example use case for custom exceptions is rollbacks for database transaction queries. If that sounded like jibberish, some databases allow what are called transactions. You are allowed to start them, save them, and commit them. They wrap around database queries, essentially encapsulating them, and if the queries fail, allow you to undo everything that the queries did. But back to the exceptions...

Using Third-Party Code

Here is a real-world example that might seem too convenient but is entirely possible. Lets assume that we are using a third-party framework or database abstraction layer. We don't necessarily know anything about its inner workings, but we do know that it will throw an exception if any database queries fail. Now, assume that we are working on a large-scale application and that there are a a few (sets?) of queries that affect a lot of the database, and that if they were to fail, the results would be disastrous (for example: locking a database table and not unlocking it).

Well, there are a few ways to approach the problem of one of the queries failing and having the third-party code throw an exception. Here's the first way--in pseudo-php/framework code--that we might resolve any problems. This way is clean and simple and works well with the transactions.

try {
	$db->beginTransaction('mission_critical');
	$db->query("UPDATE ...");
	$db->commitTransaction('mission_critical');

} catch(DatabaseQueryException $e) {
	$db->rollbackTransaction('mission_critical');
}

If an error occured then an exception will be thrown and caught by our try ... catch statement and the database will be saved! Unfortunately, this presupposes that the exception is caught in the first place. What if the roles in this were reversed? What if instead of being the programmer taking advantage of this amazing third-party code, you are actually the developer of said code?

Making Your Own Code

Now that we're the developer of this framework/database abstraction layer, we have absolutely no control over how our functions are called. However, we can assume the worst from our users and help them not destroy their database! This might be a bit too precautionary for your liking, and you won't necessarily like this solution.

We're going to make the assumption that all of the code above is the same with the exception that there are no try ... catch statements. The coder has cleverly put their mission critical queries into a transaction, but mistakenly forgotten to account for possible errors in the queries. Well, it's time to go into our database abstraction layer!

public function query($sql) {
	if(!$this->mysqli->query($sql)) {
		throw new DatabaseQueryException($this);
	}
}
public function beginTransaction($id) {
	$this->transactions[] = $id;
	
	// begin a transaction
	$this->mysqli->autocommit(FALSE);
}
public function commitTransaction() {
	if(!empty($this->transactions)) {
		array_pop($this->transactions);
	
		// commit the transaction
		$this->mysqli->commit();
	}
}

So do you see where I'm going with this? Hint: I'm passing "$this" to DatabaseQueryException when I instanciate it. Another thing to note is that I create a stack of SQL transactions. Note: With MySQLi, the $id isn't actually supported for transactions, but for other database layers it could be. That is why I have put it there.

So, what's immediately obvious is that when be begin a transaction, we push a variable onto a $transactions array, effectively keeping track of which transactions are currently not committed. When we commit a transaction, we pop the last element off of the $transactions array, saying that we've committed it. Now, what happens when an error happens in query() and the DatabaseQueryException is thrown (and maybe caught?). Lets take a look at the definition for DatabaseQueryException and find out ;)

class DatabaseQueryException extends Exception {
	private $db;
	public function __construct($db, $code) {
		$this->db = $db;
		
		// pass an error string and code to 
		// Exception/parent class so everything
		// is properly set.
		parent::__construct($db->error(), $code);
	}
	
	// tear down / clean up
	public function __destruct() {

		// rollback any transactions that might have 
		// failed/ be unfinished
		foreach($this->db->transactions as $id) {
			$this->db->rollbackTransaction($id);
		}
		
		// remove any last references to the db object, 
		// causing its destructor to be called in the
		// process.
		unset($this->db);
	}
	
	// make sure the destructor is called if the exception 
	// isn't caught
	public function __toString() {
		$this->__destruct();
		
		return parent::__toString();
	}
}

It's a pretty straightforward class, the trick to it is DatabaseQueryException::__toString(). If you define a destructor in an exception, you will quickly find out that it's not called unless the exception is caught. The obviously solution is to explicitly call it from some function that we absolutely know will be called if an exception isn't caught. That function is Exception::__toString().

Why Use a Destructor in the First Place?

Using an exception's destructor as a clean up method is useful because a) it is automatically called when an exception is caught, and b) it is called at the end of a catch statement. Being at the end of a catch statement can give the programmer certain advantages. For example, within the catch statement you have an instance of the exception readily available. Given this you now have an opportunity to do stuff with it. You can pass it information, tell it to do things, and after all of that it will destruct as expected.

Hope this helped!

PHP5 / AJAX FTP Drag and Drop Uploader

So over the weekend and up until today I've been having fun with the PHP5 framework that I'm working on. One particular system that I'm proud of is the layers system. As it sounds, it manages layers. For example, database abstraction currently has two layers: SQLite and MySQLi. There's nothing too interesting about that. What is interesting are my current file layers: System and FTP (planned: Amazon S3 and LDAP).

With these file layers I have made it stupidly easy to transparently transfer files from one layer to another (FTP->System, System->FTP). I was proud of these generally simple classes so I decided that I wanted to flex their muscles. I made a system to ftp uploader. I added a dash of jQuery and a stupid amount of javascript and now I have myself a drag and drop uploader!

I made a quick video of it in action. Sorry for the poor quality / ugly demo text. When I have money in my bank account, I will invest in a better screen capture program, I swear! Take a look at a short video of the FTP AJAX uploader in action here.

By the way, the total amount of PHP (in the controller) to handle all that is just over 200 lines (including comments). Here's the jist of how files are transferred:

// get the file layer fos the source files
$from_system = $this->getLayer('file', $from_layer);

// get the source files
foreach($files as $key => $file_name) {
	$files[$key] = $from_system->find($file_name, FileAbstract::FILE);
}

// transfer them to the destination directory, note: write() will accept
// 3 different argument types: FileAbstract, Iterator, or a file path/name.
$this
	->getLayer('file', $to_layer)
	->find($log["last_{$to_layer}_location"], FileAbstract::DIRECTORY)
	->write(new ArrayIterator($files));

And here's how I list out files in a directory:

// get the layer
$file_system = $this->getLayer('file', $layer);
				
// find the directory, read the files from it, and set it
// as a template list
$response['files'] = $file_system->find($dir, FileAbstract::DIRECTORY)->read();

Pretty neat. The templates--using my own template engine based on this HTML parser--are equally sweet.

If you want to see an online demo, just ask in the comments :)

PHP5 BetterAccess class

So I was working on a little framework for a mini application I'm going to build soon and I decided to use object overloading because it's written in PHP5. If you haven't used the overloading functions in PHP5, they are: __get, __set, __isset, and __unset. You can read more about them on PHP's overloading page.

As I've said, this is a PHP5 framework and so I decided to make use of the ArrayAccess interface. However, I haven't actually used this interface in a while and forgot the actual functions that it requires: offsetGet, offsetSet, offsetExists, and offsetUnset. Intuitively, I thought that it must use the overload functions (__get, et al.) and so programmed everything assuming that. Unfortunately when I actually got around to test everything, there were errors. At first I decided to go in and make the minor name switches, but it being a framework, I decided if anyone but me were using it, I could have a better solution. Vague enough? Here's the nifty little BetterAccess class I came up with:

abstract class BetterAccess implements ArrayAccess {
	abstract public function __get($key);
	abstract public function __set($key, $val);
	abstract public function __isset($key);
	abstract public function __unset($key);
	
	final public function offsetGet($key) {
		return $this->__get($key);
	}
	final public function offsetSet($key, $val) {
		return $this->__set($key, $val);
	}
	final public function offsetExists($key) {
		return $this->__isset($key);
	}
	final public function offsetUnset($key) {
		return $this->__unset($key);
	}
}

Not sure what the point of this is? Let me show you:

class Foo extends BetterAccess {
	private $vars = array();
	
	final public function __get($key) {
		$ret = NULL;
		if(isset($this->vars[$key]))
			$ret = $this->vars[$key];
		return $ret;
	}
	final public function __set($key, $val) {
		$this->vars[$key] = $val;
	}
	final public function __isset($key) {
		return isset($this->vars[$key]);
	}
	final public function __unset($key) {
		unset($this->vars[$key]);
	}
}
$foo = new Foo;

$foo['bar'] = 'hi';
$foo->baz = 'hello';

echo $foo->bar;
echo $foo['baz'];

// Output: hihello

This might not seem immediately useful; however, the point of it is taste. Depending on your coding preferences, BetterAccess allows you to access a class either through overloading or using array access.

Family Vacation

Until May 29th, I will be on a family vacation so do not expect any new posts from me!

Flash Tooltips Using jQuery

This is a follow-up to my previous post about Flash embedded tooltips using javascript.

You can check out a working copy of this at http://ioreader.com/code/Tooltip2/index.html and can find a download link of all of the source code at the bottom of the article. Please note, I have only tested this on Mac browsers.

But Why?

When I first created this this little experiment a few months ago I wanted to replicate the neat window effects that the OS X gui can do. Obviously that would have been impractical for a full-blown windowing system, but for tooltips it could have easily worked. Unfortunately my Flash animation skills are lacking; however, I make up for this with Actionscript.

Is this necessary? Are poppuping up Flash versions of normally dhtml tooltips useful? In terms of practicality, no. Sometimes the tooltips themselves take a while to load up and finally display. Otherwise, with flash we can accomplish some cool things such as rounded corners, drop shadows, transparency, and neat shapes all without having to mangle with the DOM or with CSS.

And so we come to the question: but why? Simply put, it was a fun experiment. I wanted to see if I could do a better job than last time and I succeeded.

Approach and Limitations

Normal tooltips come up when you have a "title" or "alt" (or both, as is the case when pairing the <a> and <img> tags) attributes set on elements. These generally work well, but for large amounts of text get ugly. Also, HTML cannot be injected into these attribute and be expected to degrade gracefully as well.

This is where definition lists come in. As the name implies, these lists allow you to specify a string and also specify definitions for it. I chose these for two reasons. First, I could easily contain the entire tooltip within the text within a simple list. Second, the definition list lends itself well to the concept of tootlips because the definition is implicitly highly relevant to what's being defined--at least that's how I rationalized it in terms of a search engine spider parsing the HTML.

An inherent limitation with definition lists is that they are block-level elements. As such, they cannot be placed within HTML paragraphs (<p>) and similar tags. If this idea was to be actually pursued, then they should be made to simply replace normal tootlips offered by the title and alt tag attributes. In retrospect, making my life easier by doing this would have been a good idea, but oh well. I wanted to get HTML into them!

For this script, we will be dealing with Flash (and Actionscript), Javascript, and HTML/CSS. The last iteration of this script used actionscript's ExternalInterface class to deal with javascript-actionscript communications. This times decided to rely on the built in flashvars property when displaying Flash files in HTML pages.

Goals

I had several goals when making this. First, I wanted the flash version of the tooltip to act like any other tooltip in that it would be constrained by the dimensions of the browsers viewport. This is done through simple javascript. Also, I wanted to have it be able to degrade to normal DHTML tooltips (haha.. degrade to javascript, how many times have you heard that?).

Moving to the Goals

The nature of Flash is such that all actionscripts are compiled into the final movie even if they are included into said movie from outside the movie itself. This means that even if we made changes to the actionscript file that deals with the flash side of the tooltip we would still need to open up flash and export the movie. This is a bit of a hurdle, but we will assume that people can easily jump past it. To make everyone's lives easier then, I have made a global config file. This is a configuration file shared by both the actionscript and javascript for maintainability between the two parts of the script and also for consistency between flash and javascript tooltips if the flash version is not supported.

Awesome 3rd Party Code

I mentioned earlier that I wanted rounded corners in my flash tooltip, so I went and downloaded these great actionscript drawing classes to do the job. This time instead of writing all the javascript ground up, I decided to use jQuery and its awesome flash plugin. Besides jQuery's awesomeness, using the library allowed me to handle all cross-browser inconsistencies at arms length. Finally, a function by Peter-Paul Koch at Quirksmode allowed me to get information about the viewport.

Putting it Together

Initially I wasn't used to the jQuery flash plugin so I used their sIFR example as a base and worked up from there. What an awesome plugin, development went very smoothly. On the actionscript side, everything was again quite simple to put together. The most important thing about how all this works is that first, the javascript writes the flash HTML with a width and height of 100%. Then, I just set the dimensions of the flash movie to 1x1 (any size works). The reason this was done is because everything in the actionscript works by the Stage.size. So, the flash scales to the bounding box of the <dd> and jquery sets the size of that box based on the text inside it. Everything works together in a really nice way.

Rationalizing

After the two scripts were finished and working, I created a simple tooltip.config file. This set a TT_CONF variable to an object literal (aka JSON) with configuration values that are shared between both javascript and actionscript. So, if one wants to change the font size in actionscript, they need only do it in there, export the tooltip.fla, and then the javascript will properly adjust itself with the changes. Hooray for consistency.

Conclusion

This was a fun diversion and experiment. I think last time I was overcomplicating--even though the result was rather simple. This time around I've made a rather simple script that can be seamlessly integrated into any website (although I don't suggest it).

You can get the code at http://ioreader.com/code/Tooltip2/Tooltip2.zip

I got a Wii!

Backstory

Here's the story behind it: I asked for a Wii as a xmas present last year. On the day the Wiis were in stores, my cousin was able to get one but he later sold it on eBay. About three months ago I had a chance to get one at a FutureShop (FS) over in London, Ontario. I had the money in my bank account but had no way to get to FS in time! On Monday, I went online to the FS website as I have been doing almost every day to check the store stock of the Wii and I noticed something unusual... The Wii console listing wasn't available! They must have been doing some sort of update. After an hour or so it came back and the stock for the local FS said it might be there (it had the unknown icon). I called them up and they had 14 left! Unfortunately, I didn't have the money in my bank account to buy one (altho I did have means to get there in time) and both parents were in the city! Cheated again!

I called up my mom to check on when she would be home and it wasn't for a few hours--too long I thought. She suggested I call them up, ask them if I can buy one using her credit card if she tells them the number on the phone and I supply some sort of proof. I ouldn't do that either :(

At around 5pm (store opened at 10am!), my mom called and she was on her way to FS (but in very heavy traffic). I called FS and asked if any were left and there were still two! Approximately 30 minutes after that call, my mom got to the store, called me, and was holding the last Wii!

The Games I Got

Excite Truck

About a month ago I went into a BestBuy with my sister and started playing with the PS3. It had a truck game loaded so naturally I played it--and I loved it. From that point on, I knew I wanted a truck game. Excite truck is really fun if you like this kind of game. It has a lot of different maps, all country based. The tutorials are also very good.

With Excite Truck, you hold the wiimote (wand) as if it were a normal controller. At first you want to use the arrow keys to turn and to similar things (and I found it difficult to stop myself from doing this) but its much cooler than that! You tilt the controller left or right to turn, when jumping you tilt the controller backwards to get more air and by pressing the backbutton (I think, I'm never too sure about this.. lol) you get a huge burst. Suffice to say, once you break out of the normal controller habits, it becomes incredibly fun.

Medal of Honor - Vanguard

I really wanted a shoot-em-up game and read that Crysis was not so greate but MoH was the one to go with. I'm so used to a mouse and keyboard that it was difficult to get used to the controls at first. After you generally figure them out, it's an intense game. I definitely suggest it.

Wii Sports (included)

I tried Wii Sports last. I don't know why, but it is incredibly fun. I've only tried tennis, boxing, and golf sofar. Golf is my favorite, you can work up a sweat with boxing, and I haven't quite figured out how to direct the ball to where I want it to go in tennis (without overdoing it and having the ball go out).

Conlusion

You've read it everywhere and it's true. The Nintendo Wii is amazing.

Using a Stack to Parse HTML with PHP5

Use Cases

Before we get into any of the code we should think about how a HTML / Template parser can possibly be useful. Well, with it, we can do several things: make a custom template engine, make a HTML code cleaner for such things as posts/comments on blogs/forums/etc, make a HTML Tidy script that will properly indent our html, and more.

Strategy

Off the bat it should be obvious that we're going to need to use one of PHP's perl compatible regular expression (PCRE) functions--these are denoted by the prefix "preg_". Thinking this through, we want to be able to capture every single tag in the document/text (hereafter: buffer). Lets assume we use a preg_match_all or a preg_replace. These will successfully find all of the tags but it won't get us the text in-between. You might be wondering: why is the text in between the tags important? Well, HTML and XML follow a tree structure, such as:

<root>
	<sub>
		<sub>
			text
		</sub>
	</sub>
</root>

So if we only find the tags through a preg_match_all, then we will have no way of building a new fixed/compiled version of the buffer because we won't have any of the available text. If we use a preg_replace/preg_replace_callback then we can replace all of the tags properly but then making sure that all of the tags open and close in their proper order would be ugly and very involved.

There is another great PCRE function available to use that many people often don't use. This function is preg_split. This function will allow us to split up the buffer into text and markup nodes. Perfect! preg_split has a flags parameter that allows us to change the results that we recieve from it. The option that we will choose is "PREG_SPLIT_DELIM_CAPTURE", which the PHP Manual defines as

If this flag is set, parenthesized expression in the delimiter pattern will be captured and returned as well.
If that seems like jibberish, it simply means that the array returned from preg split will include both the things in-between the split regex pattern and what the pattern matched as well.

Alright, so now we know how we're going to find the tags and the text. Lets think about how we're actually going to parse them. We know that the markup will be in a tree-like format and most tags will open and close (there can also be non-closing tags). Lets look at this as a challenge. We have an array of opening and closing tags (as XML disperesed among array elements that have normal text. We could make a regular expressions to match opening and closing <sub> nodes but chances are that in a more complex tree the regular expression will not match the proper closing tags. Given that we are on the first <sub> tag and we want to find its </sub> and not the <sub> that's within it, we can parse it top-down as a stack. let me put this as a series of events:

  1. found <sub>, push the first <sub> tag onto the stack
  2. found <sub>, push the second <sub> tag onto the stack
  3. found text
  4. found </sub>, pop the second <sub> off of the stack
  5. found </sub>, pop the first <sub> off of the stack

This clearly shows us that the last array_pop of the stack will represent the closing tag to our first <sub> node! Think this through a bit if it seems awkward. Now that we know how we want to parse the markup, lets get to it--with code!

» read the rest of this entry.

PHP Closures Update

Over the weekend I was experimenting with my PHP Closures implementation. Unfortunately I ran into some bugs, but those I was able to fix. The first and main bug that I ran into was particularly interesting and required an ugly fix.

First, lets set up an example and display it visually...

Imagine that each box in the above image represents a different function/lambda. What we can see is that there is a lambda within a lambda within a function. Simple enough. The arrows are where the problems come in. The first iteration of the Lambda class was able to reproduce the first arrow, meaning that scope variables from the parent functions were successfully brought down into child functions. This was accomplished by using PHP's get_defined_vars() coupled with extract().

Bringing the modified scope variables out of the sub-lambdas and up into parent functions (the bottom array) was somewhat trickier. First, some obvious observations needed to be made: the scope variables will only be modified when the lambda's call() method is called. Also, call() can return anything and can be used anywhere, so we can't make any assumptions about its use. Therefore, whatever the solution is, somehow it will have to take place after the call() method is called. The solution I came up solves this problem for anything within a lambda; however, I didn't want to subject the programmer to having to write the ugly hack that the lambda "compiler" creates.

Now it's time to make some simple yet important observations about variable scope in PHP. The main thing I want to bring attention to is function arguments. These tend to be rather benign things and we never think about how they affect scope--unless we are passing the arguments by reference. Most people also don't normally call their functions like this either...

<?php
strtoupper($str = "hello");
var_dump($str);

// output: string(5) "hello"
?>

The fact that the value of $str isn't changed to uppercase shouldn't be surprising. That's not important. However, the fact that $str exists after the function call is. Normally one wouldn't think twice about this simple happening, but for my closure script it is incredibly important. This means that if the program can find "->call(" and ")" then a function can be appended to this to bring the possibly changed variables into the parent scope when the function is called. This also gives the little complication of the return value of call(), but that requires a trivial workaround. Here's the end result:

// how it was:
$lambda->call($arg);

// what it becomes:
$lambda->storeCall($arg)->extrAndCall(extract(ScopeStack::getInstance()->popScope(),EXTR_OVERWRITE));

Yikes! Definitely not elegant but it works nonetheless. As I mentioned earlier, this is only a partial solution because I don't expect people to add this to the first lambda() call (because sub-lambdas have a cleaner format). Here are the results of this new solution in place:

$func = lambda(array(), '$new_test', '
	static $test;
	if($test === NULL)
	{
		lambda({
			$test = $new_test;
		})->call();
	}
	else
	{
		echo $test;
	}
');

$func->call('hello');
$func->call('');

// outputs: hello