Get Off My Lawn
Get Off My Lawn

Reputation: 36341

How to force a method to be called

I am creating an API, and I have a class called Service which has a function requireType()

$type is one of GET, PUT, POST or DELETE

final public function requireType($type){
    // Do some stuff
}

I also have a master class called API it creates an instance of the class called from the API lets call it ClassA which then extends Service.

class ClassA extends Service{

    // Writer called "$this->requireType()" method is fine to run
    public function myAction(){
        // Make sure $this->requireType() was called here before anything else gets run
        $this->requireType("POST");
        // Do some stuff
    }

    // Writer did not call "$this->requireType()" method
    // An error should occur
    public function myAction(){
        // Do some stuff
    }
}

What I would like to know, is in my API class how (if possible) can I check to see if requireType() is getting called right away in myAction()?

The API class method call looks something like this (simplified):

// This method creates an instance of "ClassA" and runs "myAction()"
// We should check to see if the person who wrote the method "myAction()" 
// called "$this->requireType()" or not. If not throw an Error
final public function execServiceRequest($clientData = ""){
    $class = $this->getService();
    $reflection = new ReflectionMethod($class, $this->action);
    $obj = new $class();
    $obj->setReadWrite($this->read, $this->write);
    $obj->initPage($this->config);
    $obj->setData($clientData);
    $obj->before();
    $response = call_user_func(array($obj, $this->action));
    $obj->after();
}

So in the end I would like something like this:

The client from example.com sends a PUT request to api.example2.com, api.example2com knows what the client sent. The method that gets called does not know, it needs to say if you are going to call me you need to send a GET request and if you don't you need to send a different request with a GET header in order to access this method.

I mostly want to add this feature so a developer that is creating new methods doesn't write code that will accept any one of the 4 header types by accident.

Upvotes: 0

Views: 107

Answers (2)

I would put the constructor in the Service class:

class Service {
  final public function __construct($type) {
    $this->requireType($type);
  }
}

that way, any class extending from service will have to be constructed with a $type and will call the function

Or, if it is important that each call to myAction()has a different type, you can have an abstract method and a defined method in your Service class:

abstract class Service {
  final public function myAction($type) {
    $this->requireType($type);
    $this->customAction();
  }
  protected function customAction();
}

that way, everyone calls myAction() with their desired type (enforced by php) then myAction() calls customAction() which has to be defined in the extending class

Upvotes: 1

Shadow Radiance
Shadow Radiance

Reputation: 1369

In the base controller constructor, set an instance variable called "calledRequireType" to false.

In requireType, set calledRequireType to true.

In... whatever code you want to check if they called it (presumably the same handler that calls xxAction, after calling xxAction), check calledRequireType and throw an exception.

Upvotes: 0

Related Questions