tags:

views:

71

answers:

3

I know that PHP4 is "dead", however there are about two dozen or so of our clients that still are located on servers where PHP4 is used, and we won't get any server upgrades until around a year or two.

I'm just about to start working on refactoring and improving our core web framework, which is now coded for the lowest common denominator, PHP4 ( eg all classes have var $foo ).

I've never done any OO in PHP4 but I'm wondering if I should make different classes for the PHP versions, and based on the version of PHP include that version? The downside I realize is that I would have to update two places if an update was made, and there may be no real world advantage to it.

So if anyone could provide tips on how they support legacy PHP versions, I would greatly appreciate it.

A: 

Make sure your classes are written in PHP 4 syntax, i.e.:

class MyClass {
    var $my; // PHP4 style declaration
    function MyClass() { // PHP4 constructor     
      $this->__construct(); // calling PHP5 constructor
    }
    function __construct() { // PHP5 constructor       
       $this->my = 1;
       ...other initialization stuff...
    }
    ...
}

So it will work great in both PHP versions.

Sergei
That's currently how all the classes are. I'm wondering if I should keep it that way until we absolutely do not make any new sites on php4/legacy servers, or keep two versions of the same class.
meder
+1  A: 

I can hardly imagine me developing anything for php4, but if I were forced to I'd likely make two codebases to keep php5 code clean and nice.

stereofrog
+1  A: 

Most of PEAR is still targeting php4, so you can use that as a "framework". I believe drupal and codeignitor are also still targeting php4 (Perhaps cakephp also?).

The biggest problem with objects and php4 is that objects are passed by-value, so you need to use references to get the usual semantics that most other languages have for objects (including php5). You have to be very careful to always assign a reference to objects. Otherwise it'll be implicitly cloned. This is tedious and very hard to debug if you mess up. Besides, it will make your code incompatible with php5. Eg.:

Creating an object:

$foo =& new Foo();

Passing an object as argument to a function:

class Bar {
  function cuux(&$foo) {
  }
}
$bar =& new Bar();
$bar->cuux($foo);

Since arguments are references, you can't pass a constant. So if you must pass NULL instead of an object, you have to assign NULL to a local variable first. Eg.:

$bar =& new Bar();
$foo = null;
$bar->cuux($foo);

Returning objects from a function:

class Bar {
  function &doink() {
    $foo =& new Foo();
    return $foo;
  }
}
$bar =& new Bar();
$foo =& $bar->doink();

Note that you MUST assign $foo to a variable, which makes it impossible to return the result of another function directly. Eg. this is illegal:

class Bar {
  function &doink() {
    return $this->foo->doink();
  }
}

It should be:

class Bar {
  function &doink() {
    $tmp =& $this->foo->doink();
    return $tmp;
  }
}

Miss just one of those ampersands and you're toast. Also, make sure you have a very good understanding of how references behave - They are not exactly intuitive.

troelskn