KML PHP Class

July 28th, 2006

I’ve been doing a lot of work with Google Earth and custom KML implementations lately, so I thought I would take some time and streamline the process in PHP. I put together a PHP5 class that cleans up the creation process of KML by using objects. The two biggest time savers for this method are more concise and legable code by not mixing PHP, and my personal favorite, no need to worry about KML formatting. Everything is passed through libtidy in the end, so it all looks nicely formatted as Google Earth is pretty picky about that.

The class also contains a compression feature for creating kmz files. It uses a simple zip library that I found in the code for phpmyadmin. Both files can be found here.

Direct knowledge of KML however is still very much required. When working with this class I reference the KML docs online at http://earth.google.com/kml/kml_tags_21.html.

A word of caution about the consistency of KML, there are several inconsistencies in KML and those are not accouted for in this script.

As with most code, it’s better by example. This is a short example for creating a basic KML document. I added a few objects to show how the class works, but keep in mind this isn’t a complete example.

# start a new document
$kml_file = new KML(’File’);

# Create a Document object
$document = new KML(’Document’);
$document->name = “Document Name”;
$document->description = “Document Description”;

# create an object in this case a style
$style = new KML(’Style’);
$style->id = “radio”;

# create a list style
$liststyle = new KML(’ListStyle’);
$liststyle->listItemType = “radioFolder”;

# add the ListStyle object to the Style object
$style->addObject($liststyle);

# add the Style object to the Document object
$document->addObject($style);

# add the Document object to the KML object
$kml_file->addObject($document);

# output the results
$kml_file->output_kml();
OR
# output the results with zip compression
$kml_file->output_kmz();

Safari File upload bug hiding content

July 27th, 2006

We ran into a very weird bug on Safari (which seems to exist in all of the versions we tested). When uploading a file if you hide content via javascript ( display=”none”), the $_FILES array is cleared out and the upload will fail. Interestingly, showing something (display=”") does not cause any problems.

The only work around we found was to not hide content on a form that is uploading content. Has anybody else seen this or found a better fix?

PHP File upload on bug Safari

July 27th, 2006

Anybody who’s tried to troubleshoot a PHP upload form on a Mac, may have run into this bug: in Safari version 1.0.3 (and possibly earlier) the $_FILES variable is not populated by the browser, causing any type of file upload to fail. This bug is specific to the Safari browser and PHP; upload scripts written in PERL (and possibly ASP) do not have this issue.

The resulting output for a file upload when running into this bug is a totally empty $_FILES array. One of the fixes we tried was referencing the alternative $HTTP_POST_FILES reference instead of $_FILES. Unfortunately that one was empty too.

There is no known work around that we’ve been able to find, but in theory creating an upload form in Flash should sidestep this problem as the Flash plugin would be doing the upload. Later version of Safari no longer have this issue, so this is only an issue when supporting older versions of the browser.

Google PageRank & Reciprocal Linking

July 26th, 2006

By now most developers must be familiar with the Google Toolbar and the green PageRank bar it contains. For those who haven’t heard of this, the PageRank is a simplified (and mysterious) rating from one to ten that says how important Google thinks a site is. The information is publicly available to anyone with browser that has the Google Toolbar installed, and it is often used by SEO (Search Engine Optimization) experts when deciding reciprocal links, another important search engine phenomenon inspired by Google’s search algorithm. The idea behind reciprocal linking can be summed up like this: Google figures that important sites will have a lot of links pointing to them, so trading links with another site, will be good for the ranking of your site. This is true in general, and infact links to a website are in a large part what detirmines a site’s PageRank.

But what is PageRank besides a number from one to ten? Despite its apparent simplicity, PageRank and pursuing reciprocal links with a high PageRank is not a panacea for doing well in Google searches. In an interview with Search Engine Guru Mike Grehan, Google Engineer, Daniel Shultz, provided this information about the PageRank system:

…if people are trying to look at what we’re doing [PageRank] and their idea is based on that single number from one to ten, then … well, they’re not going to be effective in figuring out what we’re doing at all.

So what are they doing? From what I’ve seen PageRank is an important measure of a site’s importance, but it only provides an initial rank. From that base additional factors come into play in detirmining how well a site will do in searches. One of the most important of these factors, is outgoing links. Every outgoing link detracts from where the site will return in Google’s search results, conversely links to a page (especially from highly ranked sites with no other outgoing links) raise that page’s ranking. Think of PageRank as credit that can be spent, with any credit not being spent detirmining how well your page will be returned in Google searches.

It is important to note that outgoing links are not just links going to another site. Even links to other pages internally on a site can detract from or add to a pages importance. That said, any pages are linked to on all pages (like a home page), will have a higher PageRank then those that are a few levels deep.

So where does this leave reciprocal links? While in general reciprocal links are good for sites, it may not always be the case. If two pages have the same PageRank and the same number of of outgoing links, both will benefit from exchanging links. But if one page strongly outweighs the other, or if one page already has many outgoing links, the net effect may only be positive for one side, and it could actually negatively affect the other.

Another final thing to keep in mind is that PageRank is not linear, it’s exponential. That means a site with a PageRank of 9 has a lot more weight than a site with PageRank of 8, etc. This means their outgoing links carrying more weight, and they can have more outgoing links without affecting their ranking.

Flash TraceObject

July 18th, 2006

The following code is for anybody who has been frustrated by Flash’s apparent lack of ability to trace on Objects. While trace works great at printing out the contents of variables when they are Strings or Numbers, when attempting to trace an Object all that is returned is:

[object Object]

Not exactly enlightening. However, don’t dispare! Through use of the global for function, it is possible to loop through an Object and pull out not only the values but (in the case of multi-dimensional arrays) any labels that are associated with them. A simple implementation of this would be:

for( var key in theObject )
{
	trace(indent+key+":"+theObject[key]);
}

What the above code does is loop through the Object (theObject) and set a variable called key. The key is then used to call up the value for that particular element within the Object. This works great for simple Array, but if an Object structure goes any deeper or has values that are Objects themselves, we end up with the same non-descriptive output.

Enter the traceObject function. The following code traverses the Object and calls itself recursively anytime it encounters an object. In this way it eventually will loop through all of the elements of an object, displaying all the content in a similar way that php displays arrays or objects using the print_r or var_dump functions (and remember all multi-dimensional arrays in Flash are objects.

function traceObject( theObject, level )
{
  if( level == undefined )
    level = 0;

  var indent:String = "";
  for( var i=0;i<level;i++ )
    indent += "t";

  for( var key in theObject )
  {
    if( typeof(theObject[key]) == "object" )
    {
      trace(indent+key+":");
      traceObject(theObject[key], level + 1);
    }
    else
    {
      trace(indent+key+":"+theObject[key]);
    }
  }
}

NOTE: if you are putting your ActionScript on different layers, the layer containing a function must be before the function is invoked.

SSL Cert Warnings

June 21st, 2006

Have you ever ran into user complaints when they access your website via https://domain.com and get an SSL cert error, because the cert is for www.domain.com?

I find that most sites are programmed to use the URL that is originally requested even when switching to HTTPS. For example, a user goes to http://domain.com and then clicks on a link that directs them to https://domain.com. They get an SSL cert error, because the site is really meant to be accessed via https://www.domain.com.

While this issue can be solved in the code, it’s not always practical to do so. A method that solves 99% of these issues is to redirect a browser from domain.com immediately to www.domain.com via the httpd.conf file in apache.

Here is a typical VirtualHost entry:


ServerName www.domain.com
ServerAlias domain.com
……

To redirect browsers immediately to www.domain.com, change it to:


ServerName www.domain.com
……

VirtualHost www.domain.com:80>
ServerName domain.com
Redirect / http://www.domain.com/

File string search

December 14th, 2005

Have you ever needed to know what files contain a certain string? For example: you need to know if an older file is being included in any other files or you need a list of any files that include a php delimiter. On a unix system you can do a recursive string search on all files within a directory and all subdirectories with the following command:

find directory -type f -exec grep -l ‘string‘ {} \;

The word directory should be replaced with the actual directory you want to search and string should be replace with the actual string you want to search. The search does a string match, not a regular expression, so no special character need to be escaped and wild cards can’t be used.

The command will output a simple list of all of the files that contain the string. It doesn’t return the number of times it is called or where it is being called, just that the file contains the string.

Removing a passphrase from an SSL Key

November 23rd, 2005

When a key is created for use with Apache SSL, it’s common for people to use a passphrase to restrict access to the key. From a security standpoint, this is an excelent idea, but from a practical standpoint, a very poor choice.

The issue is what happens when the server is restarted and the password for the key is not available. Think server crash at 2am, automatic reboot, all services are set to autoboot. Unfortunately, the web server will not start without the passphrase, leaving your website down until someone notices.

One option is to obtain an new cert that uses an unencrypted key, one with no passphrase. This is pretty painful and costs money. A better option is to remove the passphrase from the key and just use the same cert.

The passphrase simply encrypts the key, so when the key is required, the passphrase must be entered. Removing the passphrase involves decrypting the key. It’s important to make sure that the unencrypted key is readable only by root when the encryption is removed.

Here is the process:

Always backup the original key before first to make sure no mistakes occur:

 # cp server.key server.key.org

Then unencrypt the key with openssl. You’ll need the passphrase for the decryption process:

 # openssl rsa -in server.key -out new.key

Now copy the new.key to the server.key file and you’re done. Next time you restart the web server, it should not prompt you for the passphrase.

Self Signed Apache SSL Cert

November 23rd, 2005

It’s very useful to have a certificate that is self signed in many cases rather than pay for a cert. A self signed cert is limited to IP authentication and is less secure than one from a CA authority. It’s much preferable to use SSL with a self signed cert than regular HTTP when passing private information such as passwords accross the Internet.

Here is how it’s done:

First, create a private key for the webserver. Change directories to someplace that you have write permissions for. Note the use of several files to randomize the key.

 # openssl genrsa -rand /etc/hosts:/etc/postfix/master.cf:/var/log/messages -out server.key 1024

Then create a CSR certificate request:

 # openssl req -new -key server.key -out server.csr

The last step is to sign the cert:

 # openssl x509 -req -days 800 -in server.csr -signkey server.key -out server.crt

The next step is to copy the files into the proper location and configure apache for their use. Remember that in most cases these files should be only readable by root. This is to prevent a regular user from gaining access to the key and therefore any SSL session it is used for.

File type conversions in Bash

September 14th, 2005

This is a quick bash shell script that converts all of .html files to .php files. The file type extensions can be switched out to do any bulk conversion.

for i in *.html; do mv $i ${i%%.html}.php; done

This code was originally written by John Masson.