background top

Sorting 2-dimensional arrays in PHP (multi-dimensional array)

There have been numerous occasions where we have retrieved the result of an array and yet still needed to do some kind of sorting.  Up until now it seemed like there was no answer.  The answer was found with the function array_multisort.  The names of some PHP functions can be quite misleading but this one does what it says.

The trick to using this function is that it sorts based on columns.  The normal layout of a database table returned into an array is with each row of the table is a seperate element of an array.  The 2nd dimension of the array has the table row names as the keys with the value attached.

Database table turned into array

So there is our table represented in an array with each element as a separate row.  To sort we need an array for each column, in this case fruit and color.  We use the following code to accomplish this.

foreach ($query_result as $key => $row) {
    $fruit[$key]  = $row['fruit'];
    $color[$key] = $row['color'];
}

It seems quite unintuitive but essentially each column is a separate array with the row number being the key. Now we are able to plug this new data into the array_multisort function to sort our existing array (NOTE: the new column based arrays we created are specifically for the purpose of sorting)

array_multisort($color, SORT_DESC, $fruit, SORT_ASC, $query_result);

Basically you list the order of columns you want to search by. In this case we’re sorting by color descending first and then by fruit ascending. The last parameter is the multi-dimensional array that you want to sort.

Seems like a convoluted way of a simple sort. It’s always best to do all sorting and querying in the database but for the few situations that just isn’t possible, we have a solution using array_multisort in PHP.


LightWindow IE6 bug – image size (resizeTo)

LightWindow is an advanced “lightbox” JavaScript component that can be used for a wide range of media. We were simply trying to use it as an image gallery.  What we ran into is that every once in a while when clicking on a link to trigger the slideshow, LightWindow would fail to size the image properly in IE6.  This only seemed to happen in IE6 though reading through others experiences it seems like it may happen in IE7 as well although we never came across any problems with IE7.

When you run into a problem with someone elses tool it can be very difficult to solve the problem.  After an exhaustive search we were able to find the solution posted on a german blog at www.trilodge.de.  Although we don’t speak german it was obvious this was the solution to our problem.

Although this solution is already available from www.trilodge.de we know this will help any other developers who run into this issue as its hard to find the german solution being the blog is in another language.

The problem happens in the image loader.  It seems to think the image has loaded when it has not.  Therefore it is unable to get an accurate size.

To fix replace:

// We have to do this instead of .onload
this.checkImage[i] = new PeriodicalExecuter(function(i) {
	if (!(typeof $('lightwindow_image_'+i).naturalWidth != "undefined" && $('lightwindow_image_'+i).naturalWidth == 0)) {
 
		this.checkImage[i].stop();
 
		var imageHeight = $('lightwindow_image_'+i).getHeight();
		if (imageHeight > this.resizeTo.height) {
			this.resizeTo.height = imageHeight;
		}
		this.resizeTo.width += $('lightwindow_image_'+i).getWidth();
		this.imageCount--;
 
		$('lightwindow_image_'+i).setStyle({
			height: '100%', width: '100%'
		});
 
		if (this.imageCount == 0) {
			this._processWindow();
		}
	}
 
}.bind(this, i), 1);

With this:

// We have to do this instead of .onload
var ie = (document.all)?1:0;
this.checkImage[i] = new PeriodicalExecuter(function(i) {
	if(ie){ //THE BROWSER IS IE
		if ( $('lightwindow_image_'+i).complete && !(typeof $('lightwindow_image_'+i).naturalWidth != "undefined" && $('lightwindow_image_'+i).naturalWidth == 0)) {
			this.checkImage[i].stop();
 
			var imageHeight = $('lightwindow_image_'+i).getHeight();
			if (imageHeight > this.resizeTo.height) {
				this.resizeTo.height = imageHeight;
			}
			this.resizeTo.width += $('lightwindow_image_'+i).getWidth();
			this.imageCount--;
 
			$('lightwindow_image_'+i).setStyle({
				height: '100%', width: '100%'
			});
 
			if (this.imageCount == 0) {
				this._processWindow();
			}
			//alert('IE has been detected')
		}
	}
	else
	{//NOT IE, PROBABLY FF, OPERA, OTHER
		//this line works for all other browsers
		if ($('lightwindow_image_'+i).complete && !(typeof $('lightwindow_image_'+i).naturalWidth != "undefined" && $('lightwindow_image_'+i).naturalWidth == 0)) {
 
			this.checkImage[i].stop();
 
			var imageHeight = $('lightwindow_image_'+i).getHeight();
			if (imageHeight > this.resizeTo.height) {
				this.resizeTo.height = imageHeight;
			}
			this.resizeTo.width += $('lightwindow_image_'+i).getWidth();
			this.imageCount--;
 
			$('lightwindow_image_'+i).setStyle({
				height: '100%', width: '100%'
			});
 
			if (this.imageCount == 0) {
				this._processWindow();
			}
		}
	}
 
}.bind(this, i), 1);

If you have any other suggestions or ran into any other problems feel free to post them below and we would be happy to update the post to help others.