views:

37

answers:

3

I'm trying to create a PHP file that calls a function in another file. Some sample code:

Interface code:

interface AJAXDispatcher {
    static function dispatch($action);
}

Implementation:

class myAJAX implements AJAXDispatcher {

static function dispatch($action) {
    if ($action === "action1") {
        do_something();
}

This seems ok to me. I try to call it by first importing the file that it's in. I'm trying to make it independent of the name of the class so that I can do something like this:

AJAXDispatcher::dispatch($action);

Thought this would work as myAJAX would inherit from AJAXDispatcher, but I get the following error:

Fatal error: Cannot call abstract method AJAXDispatcher::dispatch() in ....

Anyone know what I'm doing wrong?

+2  A: 

An interface has no method implementation. It only defines a public API that classes have to implement. How they implement it, is up to the concrete classes. Thus, you cannot call methods of an interface directly, because there is no code to call. You have to call the method on the implementing class.

Have a look at the PHP Manual on Interfaces.

Gordon
+1  A: 

No, you can't do that. There are several things wrong here

  • That's now how inheritance works. Method chaining goes up the class hierarchy, now down.
  • Static methods are connected to the class. If you override a static method in a subclass, and want to invoke the subclass' version, you must reference the subclass explicitly.
  • Interfaces have no implementation. Even if the language allowed the type of call you're making, nothing would happen. AJAXDispatcher::dispatch() has no body.

You're going to have to re-think your strategy here.

Peter Bailey
+3  A: 

Interfaces with static methods don't make any sense, because to call a static method you (usually) need to know the class name.

Instead, you should make the method non-static and create an instance of myAJAX somewhere. The code that calls the AJAXDispatcher receives the instance and calls it. You can use type hinting to ensure you are getting the right instance.

interface AJAXDispatcher {
  public function dispatch($action);
}

class myAJAX implements AJAXDispatcher {
  public function dispatch($action) {
    do_something();
  }
}

class Controller {
  private $dispatcher;

  public function __construct(AJAXDispatcher $dispatcher) {
    $this->dispatcher = $dispatcher;
  }

  public function action($action) {
    $this->dispatcher->dispatch($action);
  }
}

$dispatcher = new myAJAX();

$controller = new Controller($dispatcher);
$controller->action('index');

This example uses the Dependency Injection design pattern.

igorw
So any way I do it I'll have to explicitly reference the class?
waitinforatrain
Well, you could probably pass the class name and then do `call_user_func(array($class_name, 'dispatch', $action));` http://php.net/call_user_func But I would advise against this approach.
igorw