Div, IFrame, Form: the CSS version of Scissor, Paper, Stone

An interesting browser (mostly, it has to be said, Internet Explorer) rendering issue has produced an slightly odd workaround. The problem arises from the rendering of form elements, specifically dropdowns, by the browser. These are registered as windows components and hence are rendered somewhat outside of the other HTML elements. (This is not true in Firefox and other Mozilla based browsers which have their own rendering. It is painfully true of the old Netscape 4 where all form elements show through, but there’s no fix for that at all.) The same rendering issue is also true of frames, iframes and embedded objects (albeit Flash can now be specified with a transparent background).

This gives the situation where a layer (in a div tag) over the top of a dropdown box leaves half the select box visible through the layer. E.g.

Peekaboo!
I’d like to be on top

The code for this follows:

Peekaboo!
I'd like to be on top

The solution I’ve found is that IFrames can be rendered on top of select tags. Not much use in itself, but ever since Internet Explorer 5.5 it’s been possible to give IFrames a Z-Index and render layers on top of them. So in the rendering scheme of things:

  • select beats div
  • iframe beats select
  • div beats select

Hence the ‘Scissors, paper, stone’ reference of the title. The order does seem somewhat circular

To solve the IE rendering problem we can insert an iframe between the div and the select with the same dimensions as the div tag over the top, as follows:

Peekaboo!
I’d like to be on top

With the following HTML code

Peekaboo!
I'd like to be on top

Class type hinting in PHP 5

PHP 5’s OO structure is way ahead of PHP 4 and has so many ‘proper’ object oriented concepts built into it that writing well-structured code is much easier than ever. The problem that PHP faces (and may always face) is that being a loosely-typed language (click here for an explanation of the differences between PHP and other languages) there’s no real way to enforce the type of objects that are passed between methods, or to overload methods in the sense of the word used by Java, C# and other OO languages.

One thing that PHP5 does allow, however, is what they call ‘class type hinting’. This allows you to specify the type of object which is passed into a method and, if a variable is passed in incorrectly, then a runtime error is generated. E.g.

class Foo
{
  public function __construct(Bar $bar)
  {
  }
}

$foo = new Foo($bar);

This will throw an error if $bar doesn’t contain an object of class Bar.

This is a step forward in that at least you get a warning about your code breaking closer to where it actually happened than, perhaps, five methods down the line when you actually try and do something with the incorrect object, but there are a couple of parts of the implementation that I still don’t really like.

The first problem is that the error message only gives the line number of the method that’s called, not the callee so there’s still some back-tracking to find the source of the error. Still, beggars can’t be choosers…

The other is that some of the built-in types don’t seem to be recognised. Therefore you can specify your own classes by name but using ‘String $myString’ or ‘Array $myArray’ doesn’t wash with the interpreter. This means you have to leave those untyped, which kind of defeats the purpose in some cases.

The other issues are really to do with a wish-list. What would be really good would be:

  • Overloading: to be able to define more than one method of the same name.
  • Specifying the return type from a method. E.g. Foo $foo = $new Foo(); Bar $bar = $foo->makeBar();

I don’t know whether that’s ever going to be possible given loose typing but I don’t think PHP 5 will be regarded as a true rock-solid OO language without them.

JavaScript Haiku

There are a few sites on the web which will generate haiku’s using a set of code rules. I think I can lay claim to have written what could be the world’s first (and only) haiku actually in JavaScript. I’m quite interested in the idea of code being poetry, but just generally not interested enough to do anything about it…

It even has a title which relates to its content, which is:

Fear of tomorrow

now = new Date();
day = now.getDate();
alert(day+1);

Review of ‘The Mapper’, Spectrum Adventure Game

I’ve found that the adventure game I wrote for the ZX Spectrum when I was 17 got a pretty good review in Your Sinclair. I never noticed at the time as I went off to University (and there certainly weren’t a flood of royalties – it was the end of the Spectrum heyday).

The game was published by Zenobi Software, who published a large number of adventure games on the Spectrum, and written using the Professional Adventure Writing System (PAWS). I think I made £60 out of it… Still, I was proud of it at the time and seeing it reviewed in a national magazine is very satisfying.

You can read the review here on the Your Sinclair tribute site

Microsoft ISV programme

Microsoft have recently launched a new programmed for Independent
Software Vendors. Basically, as long as you’re commited to developing a
saleable Microsoft product over the next two years then you get an
excellent deal on an MSDN subscription.

It’s similar to the Action Pack, so there are licensing
restrictions on the software, but still a bargain.

Microsoft Empower ISV Programme

Monty Hall problem and simulation

There’s been a bit of a debate on the forum at Freelancers.net about the Monty Hall problem. The crux of the problem is:

  • There are three doors. Behind one is a car, behind the other two a goat.
  • The contestant picks a door.
  • One of the other doors is opened to reveal a goat.
  • The contestant is then asked if they want to stick with the door they chose originally or change to the other unopened door.

Is it better to always stick or always change?

Remarkably, you have a 2/3 chance of winning if you decide to change every time.

To help sort things out, I wrote a little simulation program:
Monty Hall simulation.

And here is The Wikipedia entry on the Monty Hall problem.

TRUNCATE TABLE on MySQL InnoDB databases

Having come up against the extremely poor performance of using TRUNCATE instead of DELETE on MySQL InnoDB tables (see previous post MySQL Truncate slow performance problems) I thought I better come up with a solution that didn’t mean leaving a table to clear for an hour.

The solution is to use a combination of SHOW CREATE and DROP. DROPping a table is very quick indeed, so as long as you have the CREATE code to hand then it’s a simple matter to empty a table. The main thing to watch out for with InnoDB tables is foreign key constraints which are easily disabled.

Some sample code to use this from within PHP is shown below

function truncateTable($tableName)
{
   //Grab the code to create the table
   $sql = "show create table " . $tableName;
   $dataSet = DataHandler::loggedDbQuery($sql);
   $result = $dataSet->fetchRow();
   $createSQL = $result["Create Table"] . ";
        SET FOREIGN_KEY_CHECKS=1;";
   //Drop the table. We have to disable foreign key
   //checks, which means running the whole thing
   //from the command line
   $sql = "SET FOREIGN_KEY_CHECKS=0;
      drop table " . $tableName . ";".
      $createSQL;
   DataHandler::multipleDbQueries($sql);
}

This is used in conjunction with a static method I’ve created to run a standard (single) SQL query from within PHP called DataHandler::loggedDbQuery (which works with PearDB, which is where the fetchRow() method comes from) and a multi-line query function I have developed and wrote about in Multiple SQL queries using MySQL and PHP and referred to as DataHandler::multipleDbQueries($sql).

Multiple SQL queries using MySQL and PHP

Something that I’ve had problems with using MySQL/PHP is the limitation of only being able to run one line of SQL at a time. Using something such as Microsoft SQL Server it’s possible to write multiple lines of SQL and run it all in a single database call. Until stored procedures (in MySQL 5) are available (i.e. when it seems that the database engine is ready for a live environment) I’ve put together the following static method ‘hack’ using PHP’s exec() function (assuming you’re using PHP 5’s object syntax – otherwise just paste the code into a regular function):

class MySQLInterface
{
   public static function multipleDbQueries($sql)
   {
      $file = fopen(TEMP_CSV_LOCATION .
         "temp_query.sql","a+");
      fwrite($file,$sql);
      fclose($file);
      exec("mysql -u " . DB_USERNAME .
         " --password=='" . DB_PASSWORD .
         "' " . DB_NAME . " < " .
         TEMP_CSV_LOCATION .
         "temp_query.sql");
   }
}

What this allows you to do is to pass in a SQL string and have it executed as if it was being run from the command line. This is especially useful if you need to disable foreign keys for some reason. e.g

$sql = "SET FOREIGN_KEY_CHECKS=0;
   drop table oldTable;
   SET FOREIGN_KEY_CHECKS=1;"

MySQLInterface::multipleDbQueries($sql)

Downsides of this are

  • Requires command line access to mysql
  • Liable to SQL injection

Since i’m working within an internal system I have control over both of these and the code seems to work particularly well.

Optimising MySQL a query with packed keys

I’ve been learning more about MySQL lately and particularly optimising
SQL queries on large tables. Large, in this case, being at the moment
hundreds of thousands of rows but soon to be millions. One of the
problems I’ve had is that MySQL sometimes decides not to use an index
even when a handy one seems to have been created for it. The root of
this appears to be to that with B-tree indexes if there are a large number of records with similar looking values then the MySQL engine may decide that it’s just as much effort using the index as to search the whole table.

The answer appears to be adding PACK_KEYS = 1 to the end of a create
table, or running the SQL command ALTER TABLE MyTable PACK_KEYS = 1 once
the table has been created. In effect, this takes account of the
similarity of adjacent keys. In our case we have a large column of field
type bigint(21) where the starting digits of the index are timestamp
generated. So, at present, we end up with a few tens of thousand rows
all starting with 108xx. Enabling packed keys means not only that the
index is smaller as MySQL only needs to store the differences between
keys (plus an extra byte to keep track of where the similarity starts)
but also that the index is actually of some use i.e. doesn’t become a
large, flat structure.

One down side of using packed keys is that inserts are slower, but given
that the system we are building is inserting each row once and then (in
theory) never touching it again that’s a small price to pay. The other major drawback, however, is that packed keys only works on MyISAM tables at present and not InnoDB. This actually isn’t much use to me as the large inserts we occassionally have to do would end up with MyISAM locking the table for perhaps an hour or more.

Pack keys
reference in the MySQL manual