Simulating multiple inheritance in PHP 5 via the runkit extension

by Rudd-O published 2006/03/14 22:47:50 GMT+0, last modified 2013-06-26T03:24:27+00:00
How to simulate multiple inheritance in PHP using the runkit extension

Update: there's a serious bug with this approach and `runkit` 0.7. For an updated approach, try Revisiting multiple inheritance in PHP. Oh, there are RPM packages for runkit here.

Here's some code that will help you simulate multiple inheritance in PHP 5 with maximum portability. This requires the runkit extension for PHP, regrettably. Hope runkit gets rolled into baseline PHP 5.

This code also emulates the aggregate_methods function from the Object aggregation functions in PHP 4.

Say you have:

<?php
class Foo {
   function example() {
       return "foo!\n";
   }
}

class Bar {
   // initially, no methods
}

// copy the example() method from the Foo class to the Bar class, as baz()
runkit_method_copy('Bar', 'baz', 'Foo', 'example');

// output copied function
echo Bar::baz();
?>

We can generalize the runkit_method_copy to work with all classes:

<?php

function aggregate_methods($destClassName,$srcClassName) {
    $methods = get_class_methods($srcClassName);
    foreach ($methods as $m) {
        runkit_method_copy($destClassName,$m,$srcClassName,$m);
    }
}

function inherits_from($destClassName,$srcClassNameList) {
        foreach ($srcClassNameList as $s) {
                aggregate_methods($destClassName,$s);
        }
}

?>

Now, the function call will work for all classes without modification (honorable exception made of classes whose method namespaces clash). This little bit of magic lets you 'inherit' from multiple classes, taking full advantage of methods defined in other classes (such as classes written explicitly to work as mix-ins). Most of the introspection machinery won't exactly work, but those are the breaks.

In practical terms:

<?php

class A {
    ...A' methods here...
}

class B {
    ...B' methods here...
}

class C {
    ...C's methods here...
}

class MultipleInheritedClass {
    ...this class' methods here...
} inherits_from('MultipleInheritedClass',array('A','B','C'));

?>

So there you go: there is multiple inheritance available in PHP!