Archive for the ‘Web Development’ Category

PopupGallery, now pageable

Monday, April 9th, 2007

Some of you may have used the PopupGallery available at Yellow Swordfish. In the last few days I made changes to it so that the hover gallery automatically becomes pageable if there are too many pictures to be fitted on the page. You can see an example at my test site. The modified plugin package is available here.

Date and Time in PHP 5 and MySQL 5

Tuesday, March 13th, 2007

Time for a little technical post.

Date and time manipulation are one of the most common components in web applications. This is true for a few reasons:

  1. Web applications can have users coming from anywhere around the globe, under many different timezones.
  2. Chances are that you receive date and time information when the user does something. For instance, a user sends an e-mail and there is a timestamp in the message header.
  3. Chances are that you want to do something about the timestamp. For instance, sorting e-mails according to the timestamp before showing them to the user.

Unfortunately, the PHP date and time manipulation functions are anything but properly documented by the PHP documentation team. This causes a lot of grief and frustration among novice PHP programmers. Here, I will talk about how to handle dates and times in a PHP 5 + MySQL 5 setup.

Always store dates and times in the UTC timezone.

This is a good idea for 3 reasons:

  1. The UTC time reference is the most precise and least debatable there is on Earth because it is based on atomic time and takes the Earth’s rotation speed into account for compensation. Furthermore, it has never been, is not, and will never be subject to the daylight saving rule.
  2. The UTC is already the preferred reference timezone among application developers. The Unix Epoch, for instance, starts on midnight of January 1st, 1970, UTC time. Therefore, storing dates and times in UTC will allow easier interoperability with other applications right off the bat.
    1. A consequence of the above is that robust conversion routines to and from UTC is likely to be available in any programming language you pick (including PHP).
  3. You never know when you may need to move or deploy your web application to a host on a different timezone, therefore you don’t want to rely on the server’s timezone for storing and converting dates and times.

Dealing with date and time in PHP 5

Let’s face it, the php.net documentation sucks. One of the issues I see in it is that it fails to adapt to the OOP paradigm. It’s a shame that OOP has been introduced to PHP 4 and 5, and yet the documentation is still largely function-oriented. PHP 5 comes with a class library, but most people whom I have talked with do not know how to use it because the classes are not well documented. As such, most PHP 5 projects are still largely procedural. My goal here is to bring you a little bit of enlightenment by explaining how to use those classes.

  1. First, you need to create an object to represent the timezone. This step is not strictly necessary, but is recommended because in a globally connected world, a time value by itself is meaningless. The DateTime constructor can optionally take it as an argument, which is the way I recommend you to use it.
    $timezonename = 'America/Montreal';
    $mytimezone = new DateTimeZone($timezonename);

    Note that $timezonename can be any timezone name supported in the Olson timezone database (a.k.a. zoneinfo) or any of the few extra ones. You can see the full list in Appendix I of the php.net documentation.

  2. Only then do you create the DateTime object.
    $datetimestring = '2007-03-13 23:10:00';
    $mydatetime =
      new DateTime('2007-03-13 23:10:00', $mytimezone);

    The exact acceptable format of $datetimestring is the same as the GNU Date Input Formats, in case you have not found out from the php.net documentation already.

  3. Now, let’s try outputting it as a string. The bad news is that you should not do echo $mydatetime; The good news is that you can decide what string representation to take by using the DateTime::format() method.
    $mydatetimeformat = 'Y-m-d H:i:s e';
    /**
     * 'Y' for year, 'm' for month, 'd' for date,
     * 'H' for hours, 'i' for minutes, 's' for seconds,
     * and 'e' for the timezone name
     */
    echo $mydatetime->format($mydatetimeformat),
      $mydatetime->format('I')?' DST':'';
  4. Perhaps you would like to see the date and time in another timezone? No problem, PHP has that covered.
    $mytimezone2 = new DateTimeZone('Asia/Tokyo');
    $mydatetime->setTimezone($mytimezone2);
    echo $mydatetime->format($mydatetimeformat),
      $mydatetime->format('I')?' DST':''; 

Word of caution

The constructor method of DateTime is supposed to return false on failure, so you may be under the impression that you can rely on it to validate date and time strings. For instance:

$montrealtimezone = new DateTimeZone('America/Montreal');
$bogustime =
  new DateTime('2007-03-11 02:30:00', $montrealtimezone);

The above snippet is supposed to result in $bogustime holding the value false because ‘02:30:00′ is not a valid time on that date due to Daylight Saving Time entering into effect. Unfortunately, the constructor does not catch the mistake and will return you a DateTime object representing March 11th, 2007, two-thirty in the morning, Montreal Daylight Saving Time. It is a bug that I recently discovered in PHP 5.2.0 and submitted to the php bug database. It does not seem to be fixed as of this writing, where the latest stable released version of PHP is 5.2.1. You can check the status of the bug here: http://bugs.php.net/?id=40340.

Edit:
A comment by Eric has prompted me to clarify that the above bug is NOT caused by an outdated zoneinfo database. You can test it by trying to instantiate a similarly bogus date of a past year, while having the most up-to-date zoneinfo database installed.

How to properly embed Macromedia Flash objects

Tuesday, March 14th, 2006

If any of you has been visiting this blog through Mozilla with the Tidy-based HTML validator extension, you may notice that the page now validates perfectly with no error and no warning at all, instead of having 1 warning like before. The problem had to do with the Flash movie from YouTube. The HTML code that YouTube supplied contained the <embed /> tag, which is not recognised by the W3C’s HTML and XHTML specifications. Being a standard-compliant freak, I have been asking around for weeks about how to get rid of the warning; and then, just an hour ago, I read the HTML 4.01 specifications again and found >this<.

Before - the original code from YouTube:


<object width="425" height="350">
    <param name="movie"
        value="http://www.youtube.com/v/iIIoc8R26iM" />
    <embed src="http://www.youtube.com/v/iIIoc8R26iM"
        type="application/x-shockwave-flash"
        width="425" height="350" />
</object>

And after - the new code I figured out:


<object width="425" height="350"
    data="http://www.youtube.com/v/iIIoc8R26iM"
    type="application/x-shockwave-flash">
    Yellow Fever
</object>

Notice, however, that Microsoft Internet Explorer does not understand the second, correct version. It is a long-known fact that Internet Explorer’s HTML rendering engine is broken in many different places, with respect to the W3C specifications. Therefore, JavaScript needs to be used to determine which version to use:


<script type="text/javascript">
IEString = '<object width="425" height="350">'+
  '<param name="movie" '+
  'value="http://www.youtube.com/v/iIIoc8R26iM" />'+
  '<embed src="http://www.youtube.com/v/iIIoc8R26iM" '+
  'type="application/x-shockwave-flash" '+
  'width="425" height="350" />'+
'</object>';
MozString = '<object width="425" height="350" '+
  'data="http://www.youtube.com/v/iIIoc8R26iM" '+
  'type="application/x-shockwave-flash">'+
  'Yellow Fever'+
'</object>';

// The "browser" string is assigned by a nice
// browser detection script from quirksmode.org
if(browser == "Internet Explorer")
  document.write(IEString);
else
  document.write(MozString);
</script>

I hope this little piece of information helps those of you who want to use Flash on your webpages while being standard-compliant. I admit that the script does not take even other browsers like Opera, Safari, and Konqueror into account. I have not used those browsers long enough to know their behaviours off the back of my head. You are welcome to leave comments to help me improve the script. Notice also that, due to the default text processing options of WordPress, just pasting the script section inside a post usually does not work. You need to employ one of the solutions described >here<.


Bad Behavior has blocked 122 access attempts in the last 7 days.