Hackery, Math & Design

Steven Wittens i

PHP 5 references fun: clone for PHP4.

An issue that's popped up recently in Drupal is PHP5 compatibility. At first, this looks like a no-brainer. Drupal does not use any advanced OO features, so most code runs on both PHP4 and PHP5.

There is a however a nasty change in PHP5: objects are now always passed by reference. Variables hold a handle to the object rather than the object itself. This brings PHP more in line with other OO languages (like Java) and removes some of the ugly from PHP OO code, but it also means that objects are treated differently from all the other types. Old code that depends on having objects copied when not passed by reference will break.

Fixing this is tricky. PHP5 gives you the clone keyword to copy objects with:

<?php
  $copy = clone $object;
?>

And surprise, surprise, PHP4 does not consider this to be valid code. It doesn't even parse, so you couldn't enclose this with a version check. To get around this, you need a rather ugly hack.

The following code works the same as the above, in PHP5:

<?php
  $copy = clone($object);
?>

PHP 4 on the other hand will think clone() is a function. The obvious next step is to conditionally declare this function if PHP4 is running. The only problem there is that the function definition will not parse in PHP5 because clone is a special keyword. To get around that, we have to use eval() to postpone parsing. Here's the finished hack:

<?php
  if (version_compare(phpversion(), '5.0') < 0) {
    eval('
    function clone($object) {
      return $object;
    }
    ');
  }
?>

In PHP5, the native clone keyword will clone the object, while in PHP4 the cloning will happen when the object is passed by value to clone().

We still need to go over the Drupal code and check for reference problems, but at least now we can clone objects consistently.

Drupal  PHP
This article contains graphics made with WebGL, which your browser does not seem to support.
Try Google Chrome or Mozilla Firefox. ×