Pergunta

Here's the premise:

I have many classes where I need to perform an action BEFORE any method from any of the classes is called, my solution was to have all of the classes extend a parent class which would define a call() function which would look like:

public function call($method){
    //do the something I need to do before method calls
    $params = func_get_args();
    //remove the $method param from the $params array
    unset($params[0]);
    return $this->__call($method,$params);
}

And then simply call the call method and specify the actual method I wanted to call, that way the method would get called, but inside the call method (which the class inherits from my parent class) I could carry out the action I needed to carry out before the specified method gets called.

This needs to be able to support arguments that could be arrays or strings, so anything that involves imploding an array of arguments will not work (since this would assume all arguments are strings).

I am not sure if what I have above makes sense, and I wanted to check and see if I'm going about this the wrong way or not.

Any ideas/thoughts would be greatly appreciated.

Thanks!

PS: I should note that my description of the situation above makes it sound like the reason the child classes extend the parent is simply for this purpose, in reality there are more reasons (my parent class extends Zend_Db_Table_Abstract and my database models extend the parent).

Foi útil?

Solução

__call is called automatically, if it's defined, whenever you try to call a function that doesn't exist. That's why it's a "magic" method. It seems odd to me to use it directly, rather than in the context for which it is intended. Here, you might as well have named it anything.

You could definitely use the power of __call to your advantage here. Try naming all the member functions with an underscore before them. So, if you before had $this->print() you would now have $this->_print(). Then, in your __call function, add the underscore and call the function using call_user_func_array(array($this,"_$name"), $params). Now you can call your functions normally (well, without the underscore).

Still, I wouldn't suggest using __call except as a convenience. Long-term it is best to just call any code that you want to run directly.

Outras dicas

I better/cleaner alternative might be to setup an Event and Listening system, like the Doctrine Events System. (That code is actually from the Common library, not the ORM part.) But you will need all your methods to dispatch the events.

I try an avoid using __call as much as possible because it makes your code harder to understand and maintain, though I think it's fine to use in Plugin systems.

Thank you for suggestions, I was a kind of barking up the wrong tree, but here is the solution I came up with:

public function call($method){
    //do the something I need to do before method calls
    $params = func_get_args();
    //remove the $method param from the $params array
    unset($params[0]);
    return call_user_func_array(array($this,$method),$params);
}

Thanks again guys!

you can get the method parameters directly from the __call parameters:

function __call($method, $args) {
    return call_user_func_array(array($this,$method),$args);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top