PHP Exceptions and Namespaces

I’m way too late to the PHP namespace conversation. Initially I just didn’t see the benefit of namespaces, but now I’ve seen the light.  The other issue was the production environment at work didn’t support  namespaces – I own that problem too.  Basically for way too long it was a big fail fest.

But now angel choirs are singing and I’ve seen the light.  I preface this post with these details in case you already know what I’m about to write about.

I just spent 20 minutes trying to figure out why the same pattern of code worked in one place but not another.  I’m trying to validate date strings in form submissions and had some code like this:

function validateDate()
{
	try
	{
		$dt = new \DateTime( $fieldValue );
	}
	catch( Exception $e )
	{
		return false;
	}

	return true;
}

The error I was seeing was an uncaught exception for an invalid date format.  That’s exactly what I was trying to prevent!

It took me way too long to realize that I needed to namespace the Exception class.

The solution is either to

use Exception;

at the top of my class file or to rewrite the function.

function validateDate()
{
	try
	{
		$dt = new \DateTime( $fieldValue );
	}
	catch( \Exception $e )
	{
		return false;
	}

	return true;
}

 

TLDR: Make sure you namespace the class names in your catch blocks otherwise it’s ignored and the exception is not caught.

Advertisements

JSON Streaming Output

I recently put together a simple little bit of code to handle streaming large amounts of JSON formatted data to the browser.

In order for you to see any benefit from this, you will need to have the following scenario.

You have a response you’re sending back with some meta information about the response – maybe a response code, or error messages or a single record.

You also have a number of rows to send back as a member of the main JSON object.

These rows don’t all need to be the same object, but you can only have a single variable that you stream.

This allows you to fetch and send a single database row at a time instead of building up a huge response object in memory on the server.

It builds up a response that looks like this (the data in “rows” is streamed one line at a time):

{
    "success":true,
    "rows":
    [
        {"id":1,"random_data":"a6b1e15cc6523e87cb8d5a6a0ea39dbc61842b23"},
        {"id":2,"random_data":"12ae19125e2182294433e835ee8dc7e403154fdd"}
    ]
}

Zend Framework – ZendMail timeout in validate hostname on a mac

I develop on a Mac. I love my Mac. I use Mamp Pro for my *amp stack. After beating my head against the wall for a couple of hours, including several trips to GoogleLand, I finally found a stackoverflow article about iconv_strlen causing execution timeouts.

I am now upgraded to Mamp Pro 2.x.

Happy news: it upgraded my mysql without losing any data – in fact I didn’t need to do anything.

Concerning news: it warned me that my “templates” had changed. I had changed my php.ini files. That might prove to be a pain down the road – we’ll see. I did take a backup of them.

COMET Update – Iframes block AJAX

AJAX and COMET do not peacefully co-exist.

You’ve been warned.

While the COMET iframe is loading, no ajax calls will complete – the ajax calls are blocked by the loading iframe.

Workarounds:

  1. Remove ajax from the page
  2. have the code that initiates ajax calls suspend the comet and re-initialize it after the ajax is done
  3. Change to web sockets – that’s where I’m heading.

Fantastic Friday Function – Alternate with Namespace

Here’s a freebie that can be used immediately without any supporting libraries. This will be available in the near future in my opensource php framework: tgsf It’s released under the GPLv3.

Use it like this:

<?php

for ( $ix = 0; $ix < 10; $ix++ )
{
	echo alternateNs( 'one', '1','2' ) . PHP_EOL;
	echo alternateNs( 'two', 'a','b' ) . PHP_EOL;
}

And here is the function:

<?php

/**
* Alternate with a namespace
* The first argument is a namespace to enable multiple calls in a single loop
* Call with a set of arguments and this function will return them based on a modulus of the quantity of invocations
* in other words, each time you call this function it will return the next item in the list of parameters.
* to reset, call with a namespace and different arguments
*/
function alternateNs()
{
	$args = func_get_args();
	$ns = array_shift( $args );
	$argCnt = count($args);

	if ( empty( $ns ) )
	{
		throw new Exception( 'alternateNs called without a namespace' );
	}

	static $cache = array();

	if ( empty( $cache[$ns] ) )
	{
		$cache[$ns]['current'] = 0;
		$cache[$ns]['items'] = array();
	}

	$items =& $cache[$ns]['items'];
	$current =& $cache[$ns]['current'];

	if ( ! ( $items === $args ) || $argCnt == 0 )
	{
		$current = 0;
		$items = $args;
	}
	else
	{
		$current++;
	}

	return $argCnt>0?$args[$current % $argCnt]:'';
}

PHP based COMET Using iframes

So I’m doing some research into, and will probably be using COMET for a project I’m working on. Yes, I know that the Apache-PHP combination is not the best for COMET, however this will be on an administrative dashboard with one or two simultaneous users at most.  I’m no COMET expert – this is my first foray into the technology.  If I learn amazing things while doing a live implementation I’ll write more articles.

While searching I ran across several tutorials and some code, but nothing that was a simple 2 file “Here’s how it’s done” example.

The basic premise (this is not new stuff – I ran across stuff from the mid 2000’s while searching) is that you have an iframe that loads a long-running PHP script that is generating <script> tags.  The JavaScript in these tags must reference the parent document.  In my test code I’m referencing a function defined in the parent document.

Some takeaways:

  1. If the script that’s referenced by your iframe doesn’t output enough data before it starts outputting <script> tags, you’ll see a delay until some sort of buffer is filled up.  I’m blaming Firefox, but I’m not certain as I didn’t investigate further.  You’ll notice a bunch of white space in my sample code – that’s a whole ton of spaces to stop the delay I was seeing in Firefox.
  2. On localhost this is very fast.  I had to introduce a usleep into the code so that it wouldn’t be so fast as to be unusable.  I haven’t tested against a remote web server, but I can assure you this will be dramatically faster than ajax polling.
  3. Firefox’s javascript engine seems to process the <script> tags being returned in the iframe faster than the DOM is able to update. I view this as good news.
  4. You must output the opening and closing script tags each time you want to update the browser.  Leaving them out will cause the browser to wait until the request is loaded – the opposite of what we’re trying to accomplish.

The example code is not an infinite loop – it’s a long running script (just a very long for loop).  In practice I’ll be using other factors to determine when to break out of an output loop.  The project requirements call for this to be running for hours so we’ll find out if that tests the limits of what this approach can handle.

Download the code