404 Headers and Images!

December 11th, 2007

For dynamic systems sometimes we rely on the use of a 404 redirect to manage exceptions. The problem with this is that sometimes we are caught between a rock and a hard place. The rock, is the browser receiving the 404 header before we have a chance to tell it that it’s not actually a 404.

Take this example of a 404 apache redirect:

header(”HTTP/1.0 200 OK”);
echo “I like cheese and I like cake.”;

What’s the problem? Nothing at this point and this is because browsers are able to quickly read and understand the new header before it pushes out the content to the browser window. It’s the same when you deal with streaming images too, you can:

header(”HTTP/1.0 200 OK”);
header(”content-type: image/png”);
print_r(file_get_contents(’my.png’));

This will work okay too, but what about when your dealing with cookies? It’s hard enough for a browser to set/forget cookies when you tell it too, but some browsers are definately not happy when you try and set a cookie on an image - I guess in their defense, who needs a cookie for an image? Well, we do!

A quick way around this, is to use mod_rewrite, within apache instead. This will then allow you to get a 200 OK by default, so your not confusing the situation when you send in multiple headers and then a cookie all in one transaction. That way, some of the less-coder-friendly browsers will be able to pick it up in a snap.

As soon as we work out exactly why - we will let you know!

PHP/Soap Arrays with Single Elements

November 13th, 2007

I’m sure you have run into this before. if an Element is defined in the Soap WSDL and a single element is returned - it is treated as an object in the Soap Results, and not an array.

Turns out there is a quick fix:

  $x = new SoapClient($wsdl, array(’features’ =>
SOAP_SINGLE_ELEMENT_ARRAYS));

Thats it. If a single element is returned, PHP will handle this is a single element array, and not as an object! Handy to avoid all those if( is_object())   elseif( is_array()) constructs in your code!

Soap Headers with PHP Inbuilt Soap Toolkit

November 13th, 2007

Soap Headers are great, and the inbuilt Soap Library in PHP 5 allows you to add headers very easily:

$Headers[] = new SoapHeader( ‘http://www.test.com/test/v2′,
‘header_name’,
‘header value’,
false,
‘http://schemas.xmlsoap.org/soap/actor/next’ );
$Client = new SoapClient( $URL );
try {
$Response = $Client->__call(’methodname’, $Params, null, $Headers );

But, its a bit ugly. Particularly when using the __call() method to call the Soap method. There has to be a better way.Well of course there it. After all - this is PHP not some sort of communist language like Java :P

$Client->__setSoapHeaders($Headers );
try {
$Response = $Client->methodname( $Params )

The trick is to use the “__setSoapHeaders” function to set the headers - that way you can simply call the method on the Soap Client as per normal.

__setSoapHeaders is not in the online PHP Documentation - however it appears to work in all versions of PHP 5.X

mySQL & PI() to the Nth Decimal

October 20th, 2007

Well, it’s not the most common function on the block - infact, I’m one of a handful of people who I’ve ever seen use it, but the help that this little blerb will give, will definately not be limited to simply PI(). It’s all about the decimal places. By default mySQL will return PI() as 7 decimal points.

Well, this is fine in general principle, but what about getting really accurate when your dealing with Geo Location’s? Like, finding the distance between two points on the globe? It’s important to get as accurate as you can be when determining these distances! Afterall, the difference between 1km away, and 1.15km away can mean the difference between arriving at a friends and arriving at their neighbors!

Okay, so how do we do it? Well, as I said, PI() returns 7 decimal points, but its easy to change that! You see 7, but mySQL does see more internally because it uses the full double-precision value. Okay, so what does that mean to you? Well, normally it wouldn’t matter, but for some reason I ran across problems with it when working with re-jigging select queries.

Case in point:

SELECT *,(ACOS(COS((’-33.91451667′ * (PI()/180))) * COS((location_lat * (PI()/180))) * COS((’151.1712194′ * (PI()/180))) * COS((location_long * (PI()/180)))+COS((’-33.91451667′ * (PI()/180))) * SIN((’151.1712194′ * (PI()/180))) * COS((location_lat * (PI()/180))) * SIN((location_long * (PI()/180)))+SIN((’-33.91451667′ * (PI()/180))) * SIN((location_lat * (PI()/180)))) * 6378) AS `distance` FROM `maps_location` WHERE 1 ORDER BY `distance` ASC;

Some of the results out of this, were 1km off over a distance of 3200km’s. Not normally a problem for some people, but hey - I’m a perfectionist, so Mark and I sat and wrote an even better query.  The trick was, to make PI() think it had more decimals, before sending it in as a variable in the equation, so to do this we simply did:

PI()+0.000000000000000000000

It’s that easy!  This will force mySQL to treat this as 22 digit decimal, with the 22,21 logic.

One last thing, another quick way, if your ever stuck in less-logical languages, to get PI() is:

ATAN2(1,1) * 4;

Enjoy.

Google Maps for Mobile (GMM) and KML

October 6th, 2007

It has come to my attention and the attention of many programmers who work in multiple spaces (Wired and Wireless, Fixed and Mobile) that Google Maps lacks a certain - oomph, when you are dealing with Mobile Devices. Apart from not being able to do anything with technology as a whole - or, in most cases (except maybe the iphone) where Ajax is not supported on mobile devices - that you can’t get the full benefit of Google Maps!

Well, this sucked. The GMM release more recently has now incorporated a certain level of support however, for KML files.  How does it work? Simple! All you do, is grab your phone, download the latest version of GMM, http://www.google.com/gmm, and click “Find Location”.

Once you’ve got your location box open, simply type in the web accessible address of your KML file! The limitations of the remote KML are many, however as long as your place names are sort of short (not a paragraph!) and that your text boxes and information boxes only contain plain text (with no \r\n chars - thats ^M for you windows weenies) and there are no HTML lines in your info - then your all good!

The limitation is about 100 characters for descriptions - and about 30 for place names! So get Mobile Mapping today!

Windows Crash on Debian File Share

October 5th, 2007

Yes - you heard me right, another great way to crash your windows machine!

Recently, while rolling out some new samba shares on our network, I did all the good things that one should do to make the experience great for users, part of that was creating some new shares that were quicker to get to!

Unfortunately for me, (and my users) I mistyped one of the directories in the samba share and here is what it said:

The directory I wanted:
/whshare/media/training

The directory I typed:
/whshare/media/trianing

What did this mean to our users? Well of course, the helpdesk started getting nasty questions about why the Windows PC would crash while accessing Samba shares. The helpdesk were mighty confused by this and could not understand why this was happening.

Once it was passed back to us, we took a quick look and sure enough, crashed our VM instances! Not cool. Looking into it a bit closer, I checked the directory permissions, thinking this could be the issue.. They were fine, checked the mods, they were fine, then I checked samba conf and there it was, staring right at me… invalid spelling!

So next time you crash windows while your accessing samba shares, check to make sure your samba shares are valid - one keystroke away from mass bsod!

auto_detect_line_endings in PHP

September 22nd, 2007

Having issues with auto_detect_line_endings seemingly not taking effect in your PHP Script?Try the following - add “auto_detect_line_endings On” to your php.ini file. Restart your webserver. And most importantly - REMOVE auto_detect_line_endings from all your scripts. Its presence seems to cause auto_detect_line_endings to cease working.Also make sure you are using auto_detect_line_endings and not auto-detect-line-endings and “On” instead of “1″ - some documentation references this incorrectly!

Bash Arrays

August 16th, 2007

So simple, it’s not funny.

 #!/bin/bash

array=”1 2 3 4 5 6 7 8 9 10″

Now you can add them into a for each loop:

for i in $array; do

echo $i;

done;

So simple, even a monkey could do it!

Cache by Intersystems, 4 and 5 on Debian?

August 16th, 2007

The simple answer is Yes! Yes they do.

It requires a bit of love, but is not impossible. Run your cinstall as per normal and follow the exceptions if there are any.

Form Actions / PHP

August 2nd, 2007

Always define your form action! Never set to “” - there is a good reason not to do it this way!

If you set to “” it defaults to the current Request URI. If that was a get request it might also contain variables eg. http://test/index.php?x=1&y=2
This is fine if you either (a) have the equivalent variables defined or (b) simply don’t use them. However if your script uses those variables it can become a debugging nightmare as these will become a part of your _REQUEST stack.

If using php and you want to use the current page as the post action - use action=”<?php print( $_SERVER['PHP_SELF'] ); ?>”.

You can also use $_POST to ensure GET variables arent included - however this may or may not work with your current environment.