Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic class extend

Tags:

oop

php

Is there a way to define a class so that it extends another class only if that other class is available?

like image 228
Emanuil Rusev Avatar asked Jan 13 '11 15:01

Emanuil Rusev


People also ask

How do you extend a class dynamically in Java?

Java has two ways to do dynamic extension: forName() , and class loaders. forName() , a static method in java. lang. Class , is the simple, straightforward way to do dynamic extension.

What is extending class in PHP?

The extends keyword is used to derive a class from another class. This is called inheritance. A derived class has all of the public and protected properties of the class that it is derived from.


2 Answers

There is nothing that would allow you to do

class Foo extendsIfExist Bar

But you can monkeypatch Foo with runkit's

  • runkit_class_adopt — Convert a base class to an inherited class, add ancestral methods when appropriate

Example from PHP Manual:

class myParent {
  function parentFunc() {
    echo "Parent Function Output\n";
  }
}

class myChild {
}

runkit_class_adopt('myChild','myParent');
myChild::parentFunc();

The runkit extension is available from PECL. However, it's use is discouraged because needing it is almost always an indicator for a flawed design.


Disclaimer: I am only assuming something like the following example is the reason why you are asking your question. Disregard that part of the answer if it's not.

If you need certain functionality conditionally at runtime, consider aggregating the class you want to extend from, e.g. try something along the lines of

interface Loggable
{
    public function log($message);
}
class Foo implements Loggable
{
    protected $logger;
    public function setLogger($logger)
    {
        $this->logger = $logger;
    }
    public function log($message)
    {
        if($this->logger !== NULL) {
            return $this->logger->log($message);
        }
    }
}

In the example above, the functionality we want is log(). So instead of detecting if a logger class is available and then monkeypatching this functionality into our Foo class, we tell it to require this functionality by adding an interface Loggable. If a Logger class exists, we instantiate and aggregate it in Foo. If it doesnt exist, we can still call log but it wont do anything. This is much more solid.

like image 96
Gordon Avatar answered Sep 23 '22 02:09

Gordon


I did it on this way.

if (class_exists('parentClass') {
  class _myClass extends parentClass {}
} else {
  class _myClass {}
}
class myClass extends _myClass
{
...
}
like image 27
Kostanos Avatar answered Sep 22 '22 02:09

Kostanos