Recent activity…

Busy is good – but not being too busy. Recently I feel like I having been a bit too busy. A long time now me and my partner have been working on a new Swedish event guide. Completely written in Zend Framework, using MySQL as database and Sphinx as full text search engine. These tools are what I use normally nowadays while working on our own projects. The site has recently been launched as a beta in the spirit of release early/release often policy I have. The site is not near finished but releasing this early have already changed a few of our initial assumptions. So releasing early is good even though it sometimes can be hard to change the structure of a public website without getting in to trouble somehow.

Currently I’m also on a three month contract ending June 30th where I work three days a week with a European debt collection system in Fuengirola, Spain. I have been involved in the project every now and then for the past two years now. Fun and very interesting – but also challenging – as we’re a small team creating a complex system integrating many very different external systems (ranging from newly designed SOAP services to old COBOL systems to Windows bookkeeping applications. All in PHP of course. Beginning of July I’ll have some vacation and then we’ll just have too see what comes up.

So I thought I’d throw in an update of Wordpress and a new theme here on my blog as well… about time.

PHP, Personal

Detecting UTF BOM – byte order mark

When integrating systems with many different data sources and systems across Europe you are bound to eventually run in to issues with UTF-8 and national character sets as for example the Swedish ISO-8859-1. Even when parsing simple UTF-8 files with comma separated values things might things might popup to bite you.

One such thing is the occurrence of the UTF byte order mark, or BOM. The UTF-8 character for the byte order mark is U+FEFF, or rather three bytes – 0xef, 0xbb and 0xbf – that sits in the beginning of the text file. For UTF-16 it is used to indicate the byte order. For UTF-8 it is not really necessary.

But for UTF-8, especially on Windows, it has become more and more common to use it to indicate that the file is indeed UTF. Most text editors handle this well and you won’t ever see these bytes. As it should be.

The problems start when you are using PHP binary safe string functions such as strcmp() and substr(). Then these three bytes that won’t be visible even when using var_dump() can become bothersome. (You would however see that the string length output by var_dump() is correct and also counts the invisible bytes.)

So you need to detect the three bytes and remove the BOM. Below is a simplified example on how to detect and remove the three bytes.

$str = file_get_contents('file.utf8.csv');
$bom = pack("CCC", 0xef, 0xbb, 0xbf);
if (0 == strncmp($str, $bom, 3)) {
	echo "BOM detected - file is UTF-8\n";
	$str = substr($str, 3);
}

It’s as simple as that.

PHP

Dynamically change z-index on Google Maps markers

As many have noticed Google Maps API does not include a setIndex() method on the marker. You can set the z-index when adding a marker to the map. But it is not possible to change this afterwards.

I didn’t find a good solution to the problem when searching and had to resort to my own, hacking away on Google Maps. As I was feeling really good about myself when I had it working really well I just remembered that Google Maps Javascript API V3 has been released in Google Labs… And of course there it was. The Marker class has a new method, setZIndex(zIndex:number).

Well, version 3 of the API is still only released by Google Labs which is “home to developer products that are still in their formative stages“. So for anyone not inclined to use version 3 just yet, I’ll write down how I did it here.

As I use JQuery in this particular project the example is also using JQuery. If used in production I suggest using try/catch wherever appropriate as the solution depends on a specific dom structure.

I have the below HTML which is the container for the Google map.

<div id="indexmap"></div>

The map is created as below (you’ll have to add the lat/lng variable values yourselves.

var map = new GMap2($('#indexamp'));
var point = new GLatLng(lat, lng);
map.setCenter(point, zoom);

This, as most know, creates the actual map. Then it is time to add the markers. In my case I have a list of locations with the latitude/longitude in the actual html. JQuery helps me loop over these locations and dynamically add markers in the correct spots. This HTML looks like below. Note how each definition list have an id no with “mm_” as prefix. (Never mind any objections you have on having many definition lists like this… Never mind that these coordinates are fiction…)

<dl id="mm_0">
  <dt>...</dt>
  <dd>
    <span class="lat">61.333</span><span class="lng">31.1324</span>
    Random text
  </dd>
</dl>
<dl id="mm_1">
  <dt>...</dt>
  <dd>
    <span class="lat">61.333</span><span class="lng">31.1324</span>
    Random text
  </dd>
</dl>

What I want is the markers to be highlighted with a different icon every time I hover over a definition list element (dl). However, both have the same coordinates and one of the markers will be hidden behind the other.

So to prepare we need to make sure the actual images in the Google generated map can be connected to these defintion list id:s. The Google map have many different layers on top of each other. One layer contain the foreground images, another the shadows, mouse map definitions and so on. Each of these layers (normal div elements) have their own z-index.

In these different layers the images used have their own z-index. However, the z-index for the marker foreground image is the same as for the transparent clickable marker image. This makes it possible to use the transparent image z-index to restore the foreground image z-index. This is important as not to confuse the user when he later click on a marker…

So let’s loop over these images and give them appropriate id values as well as put the markers on the map. (No – Google does not give them id’s). This is, stripped to the bare essentials, the complete code with some comments.

// Create the map
var map = new GMap2($('#indexamp'));
var point = new GLatLng(lat, lng);
map.setCenter(point, zoom);

// Loop over the definition lists picking up coordinates
var n = 0;
$('dl').each(function() {
	var lat = parseFloat($('span.lat', this).text());
	var lng = parseFloat($('span.lng', this).text());
	var point = new GLatLng(lat, lng);

	// Create the marker with custom images
	var markerIcon = new GIcon(G_DEFAULT_ICON);
	markerIcon.image = 'marker_default.png';
	markerIcon.iconSize = new GSize(23, 30);
	markerIcon.shadow = "marker_shadow.png";
	markerIcon.shadowSize = new GSize(50, 30);
	markerIcon.iconAnchor = new GPoint(11, 29);
	markerIcon.infoWindowAnchor = new GPoint(11, 14);

	var marker = new GMarker(point, {icon: markerIcon});

	// Change the foreground image when hovering over a definition list
	// Note that the actual id's have not been created yet.
	var no = this.id.substring(3); // Exclude the prefix
	$(this).hover(
		function() {
			marker.setImage('marker_selected.png');
			// Bring this image to foreground
			$('#mf_' + no)[0].style.zIndex = 1;
		},
		function() {
			marker.setImage('marker_default.png');
			// Reset the z-index based on the transparent image
			// that has the same z-index
			$('#mf_' + no)[0].style.zIndex = $('#mt_' + no)[0].style.zIndex;
		}
	);
}

// Add id values to the foreground images, based on the
// dom structure created beneath the #indexmap div element used
// as the place holder for the map
n = 0;
$('#indexmap div > div > div:eq(6) img').each(function() {
	this.id = 'mf_' + n++;
});

// Add id values to the shadow images the same way
n = 0;
$('#indexmap div > div > div:eq(8) img').each(function() {
	this.id = 'mt_' + n++;
});

You might have to amend the code to get it working for you as I have cut’n pasted different parts. In the real code there is a lot of other things going on that would’ve made the example above hard to read. I do think however that you should be able to understand how it works.

Javascript

Moving on to php 5.3 and Zend Server CE

I have had some serious issues with one of my servers these last days. But finally things are starting to get back to normal. It seems /var was full due to mysql wreaking havoc for no particular reason. This lead – curiously enough – to network problems. If one of the discs failed because of these events or if it is somehow the original problem causing all this I really can’t tell…

Anyway, instead of quickly fixing the problem, I took the time to set up a new server running Zend Server CE with PHP 5.3. It feels good to finally move to 5.3 as well as trying out Zend Server in a production environment.

Now if I only had time to try out the new Zend Server 5.0. I’m especially curious about the job queue management. As I’ve more or less lost two days and two nights I guess that’ll have to wait.

PHP

Gartner report on PHP

A new Gartner report about PHP – PHP: Past, present and Future is mentioned in the last Zend newsletter. Even though I remain somewhat sceptical towards similar reports it is good to see that even Gartner is catching up. What they say actually do have an impact.

"PHP has been a cornerstone technology on the Web for more than a
decade. While its adoption among mainstream IT organizations has been
limited in the past, many corporate application development (AD)
projects are discovering the unique benefits of PHP."

One particular advice is especially interesting for large companies.

"Consider PHP as a supporting technology in a broader portfolio of AD
technologies, where it can provide a specialized toolset for building
Web graphical user interface (GUI) front ends to service-oriented
architecture (SOA) back-end services."

PHP is a fantastic tool for building rich web applications. It’s extensibility makes it versatile and extremely easy to integrate with modern integration solutions as Web Methods, legacy systems or just about any database technology.

To me – this has always been where PHP really shines.

PHP

Adding support for MS SQL Server to PHP in Linux

Adding support for MS SQL Server in PHP is not very difficult. Searching (Google/Bing/whatever) reveals lots of information on how to do this with Windows – naturally – but very little on how to go about it using Linux. Most people use precompiled PHP installations and I will show how to add MS SQL Server support to a precompiled PHP installation here. Those of you compiling PHP yourselves will probably understand what to do and what not based on the information here as well.

1. Install FreeTDS

First download and install FreeTDS from freetds.org. Use the following build commands to enable support for MS SQL Server (as root or using sudo).

./configure --enable-msdblib --prefix=/usr/local/freetds
make && make install

Unfortunately you need to tweak the installation somewhat as PHP still checks for files in FreeTDS that is no longer part of the installation. Just make sure these files exist (empty) by issuing the below commmands. (If you use another –prefix path above you will need to change the path accordingly)

touch /usr/local/freetds/include/tds.h
touch /usr/local/freetds/lib/libtds.a

2. Get the PHP source and compile the mssql extension

Yes – you need the complete PHP source even though you already have a precompiled PHP installed. You will not touch your PHP installation and we are not going to compile all of PHP. We need the source to be able to compile the mssql extension.

It is advised to always use the source of the same PHP version you have installed!

Unpack the source and compile the mssql extension. Remember again to change the path accordingly if you installed freeTDS in another location.

cd php*/ext/mssql
phpize
./configure --with-mssql=/usr/local/freetds
make

The extension should now be compiled and ready to install. You will find the binary in the immediate sub directory modules.

3. Install the extension

Find out where PHP expects to find extension libraries. The simplest way to check this is through the command line.

php -i | grep extension_dir

Some distributions use different php.ini files for command line PHP and the PHP web server module. So it might be good to double check using the function phpinfo() in a php script loaded through the web server (using your browser is easiest).

<?php phpinfo();

Then search for extension_dir in the configuration information displayed. For example, on my laptop running Ubuntu, the path is /usr/lib/php5/20060613+lfs.

Continuing from above without having moved away from the directory where you compiled your mssql extension.

cp modules/mssql.so /usr/lib/php5/20060613+lfs/

The extension is in the right place and all you have to do now is to make sure PHP actually loads it. To do this add the extension somewhere in the php.ini file. For example in the section Dynamic Extensions to keep it somewhere logical.

extension=mssql.so

3. Restart the web server

If using the Apache 2 web server you would normally issue

/etc/init.d/apache2 restart

4. Post installation

Well that’s about it. You should have a workable mssql extension added to your PHP installation. You should be able to continue using your platforms chosen way of upgrading PHP without affecting the MS SQL Server support.

However, you might need to dig into the freetds.conf file. If you have followed my steps without altering the installation path you will find the freetds.conf file in /usr/local/freetds/etc/freetds.conf.

Sometimes it is difficult getting the connection work without adding it to the the freetds.conf. Especially since you may have to use different values for the tds version directive depending on the MS SQL Server version. Examples:

[logisticsServer]
host = ntmachine.localdomain
port = 1433
tds version = 7.0

[intranetServer]
host = 192.168.1.145
port = 1433
tds version = 4.2

Again. Check that you are using the correct freetds.conf file and that you are using the correct tds version! More information on this at freetds.org. This and the above mentioned “missing files” that PHP is looking for are the two most common pitfalls.

Good luck!

PHP

Zend Framework 1.8 Web Application Development review

Packt Publishing sent me a copy of Keith Pope’s Zend Framework 1.8 Web Application Development a while ago. In return they asked me to write what I thought about it. I have had it lying on my desk for a while but haven’t had time to read it more carefully. Nevertheless I have actually used it every now and then. Now, after reading a bit more the last few days, I can finally give my opinion on the book.

Programming books in general

I’d better start off with telling you that I haven’t read many “pure” programming books since the mid 1990’s when I was studying at the university. I tend to stick to books on concepts and methodologies and then read online tutorials and articles when it comes to programming. Programming books are rarely worth the money as they are either reference books which gets out of date quickly (I’ve thrown away quite a few Java books over the years…) or learning by example books which you painstakingly slowly must follow line by line to build something thousands open source projects alrady built.

My thought was that this book was probably both outdated (as ZF 1.9 has been around for awhile) and probably boring in that building a web shop isn’t that interesting. I was wrong in all ends.

The book

I especially like the way Pope introduce the MVC concept in Zend Framework. In the first chapter you get a good overview on configuration, the bootstrap process, controllers, action helpers, views and error handling. Chapter two goes deeper into the specifics of the request and routing. He also briefly delves into more advanced topics as plugins and component customization. The reader quickly gets a very good grasp on how to work with MVC applications in Zend Framework.

Another thing I like is how Pope reasons about various strategies; both pros and cons as well as how and how not to do things. Good examples are chapter four where Pope gives a good explanation on the Fat Model Skinny Controller strategy and chapter five with it’s best practices regarding accessing models from views with the help of view helpers. Reasoning and explanations like this is good, especially for unexperienced developers. This – and giving optimization and testing their own chapters – makes the book better. As Pope is thowing in both Zend Tool as well as Ant into the book makes it even better still.

Summary

To sum up my opinions the structure of the book makes it easy to read at leisure as well as using it as reference later. The MVC concept and how it is used in ZF is way better explained than in the ZF documentation. (Truth be told the documentation is hopeless here.) I’ve been working with ZF a “long” time now and whether the book is better for complete beginners or programmers at least a little bit familiar with Zend Framework I really can’t tell. Remembering how I struggled to find a good introduction to various topics found in the book I belive this book is a better introduction to Zend Framework than can be found in online tutorials and articles – or even the online documentation.

However, a beginner will get more out of this book than just learning Zend Framework. He, or she, will also learn about unit tests, build procedures and best practices.

PHP

Free weather icons

The Norwegian weather service Yr.no is very popular in the Nordic region as they release weather data for free. We (as in the Swedish web development company Dotvoid AB) have used their service to create mashups and services as many others have before us.

Recently Malin Holm converted all our old bitmapped weather icons to SVG and we decided to release two png versions (60×50 and 120×100) licensed under the Creative Commons Attribution No Derivative 3.0 Unported License. All icons are named after the weather codes used by Yr.no but can of course be used for other data.

Download the full weather icon set at the Dotvoid AB icon page.

Weather icons
Weather icons
Web

10 years of English blogging

Even though I’ve lost my earliest blog posts due to an early domain change as well as a later change of blogging software I have been blogging about PHP and web development here for almost 10 years. As it is just over one year since we started our Swedish company Dotvoid AB I felt it was time to start blogging in Swedish as well.

I will continue to blog about PHP, javascript and web development here. I might even try to increase the number of posts. Oh I’ve never promised myself that before, have I ;) Anyway, our Swedish blog will not be as technical as here on dotvoid.com. Instead the blog will focus on the company and what we do as well as web development in Sweden and Europe in general.

PHP, Personal

PHP, SOAP and operation signatures

After investigating SOAP further there seems to be a common confusion regarding the difference between rpc/literal and document/literal and how it is handled in PHP. There is even a bug 49169 reported because PHP ext/soap maps all operations defined in the web service with the same signature to the first defined function or method in PHP when using document/literal style.

It is not a bug. The style document/literal is for sending messages with document data. It is not a remote procedure call. For that we have rpc/literal. So if you look at it that way it is completely understandable that only one method should be around to handle one specific type of message (document).

It is also completely correct behaviour according to the specification WS-I Basic Profile.

“In the case of rpc-literal binding, the operation name is used as a wrapper for the part accessors. In the document-literal case, since a wrapper with the operation name is not present, the message signatures must be correctly designed so that they meet this requirement.

As document/literal is the preferred style, and some implementations obviously have a tendency to dislike rpc/literal, a lot of people is going down the document/literal route without understanding the implications and what the real difference really is.

I don’t think this should stop ext/soap in PHP to use the soapAction header for routing when necessary. According to WSDL 1.1 the soapAction attribute is mandatory when HTTP protocol binding is used. Whether rpc/literal or dcoument/literal style is used is of no difference. So is this information just garbage for document style messages?

Anyways, PHP bug 46169 is to my understanding not really a bug. But it is a reasonable feature request.

PHP