Home > Mobile >  PHP Use alternate class if present
PHP Use alternate class if present

Time:06-30

I'm trying to covert old code that uses functions to use classes. Some of the old code has options only available if an advanced option is set. In the base class I have put all of the functions (methods). If the function is available as an advanced option it is overriden in the second class. If not, it should say not available in the base class. The problem is that I can't figure out how to call one class or the other, short of putting in a bunch of if's, of course.

The original function would look like this

    function Testclass() {
     if (advanced_enabled) 
       return 'Do advacned stuff<br>';
     else 
       return 'Do base stuff<br>';         
    }

Here are my classes:

    class A {
      public function Testclass() {
         return 'in base class<br>';
      }       
      
      public function SomeBaseCode() {
      }
    }

    class B {
      public function Testclass() {
         return 'in advanced class<br>';
      }       
    }

If I do this:

    $a = new A(); 
    echo 'base '.$a->Testclass();
    $b = new B(); 
    echo 'base '.$b->Testclass();

The output is

    in base class
    in advanced class

What I'm wanting to do is have the advanced class used if present. But the base class has to be present because it has methods always available. I can do this

    $a = new A(); 
    echo 'base '.$a->Testclass();
    if (advanced_enabled) {
      $b = new B(); 
      echo 'base '.$b->Testclass();
    }

But that gives me two different class variables and I would have to edit a lot of code to check each. I'm fairly new to classes so maybe I am missing some basic idea. Is there a way to do this?

CodePudding user response:

Your advanced class B needs to extend from the base class A.

class A {
  public function Testclass() {
     return 'in base class<br>';
  }       
  
  public function SomeBaseCode() {
  }
}

class B extends A {
  public function Testclass() {
     return 'in advanced class<br>';
  }       
}

Instantiation is based on the advanced_enabled flag.

$a = advanced_enabled ? new A() : new B();
$a->SomeBaseCode();
$a->Testclass();

CodePudding user response:

Instead of directly creating the class using new, use a Factory to do this for you. This factory can be a different class, or a simple function. If you use any PHP framework, you're probably using dependency injection, which can take care of this for you.

If you do not want to re-define all methods (i.e. some methods in B should be exactly the same as in A), you can use the extend keyword to have class B inherit all methods from class A you did not override. This principle is called object inheritance.

In pseudo-PHP, it would look a bit like this:

// Define classes (interface is optional, but recommended)

interface someInterface {
    public function testClass();
    public function someOtherFunction();
}

class simpleVersion implements someInterface {
    public function testClass() { /* ... */ }
    public function someOtherFunction() { /* ... */ }
}

class advancedVersion extends simpleVersion {
    public function testClass() { /* ... */ }
    // someOtherFunction is not defined here. but is still usable!
}

// Create the factory responsible for instantiating the class

function createVersion() {
  return $advancedEnabled ? new advancedVersion(); : new simpleVersion();
}

// Create the class instance (dynamically) and use it

$class = createVersion(); // $class is now either simpleVersion or advancedVersion.
$class->testClass();

Also, if you want a class B method to do something 'advanced', while also keeping the functionality of class A, you can use the special parent::something(); call to 'copy' the functionality of the base class:

class Shouter() {
    public function shout($text) {
        return strtoupper($text);
    }
}

class LoudShouter() extends Shouter {
    public function shout($text) {
        return parent::shout($text) . '!!!';
    }
}

$text = 'Hello World';

$shouter1 = new Shouter();
$shouter2 = new LoudShouter();

var_dump(
    $text,
    $shouter1->shout($text),
    $shouter2->shout($text)
);

// Output:
// -> Hello World
// -> HELLO WORLD
// -> HELLO WORLD!!!
  • Related