Hi there, i'm not sure 100% how to phrase the question and explain what i'm trying to do, so bare with me.
Basically, i'd like to try and interupt a function call or class call and do some checks first. The best way I can think to do so is to call a function that does its checks and returns the function or class e.g:
PHP Code:
function getClass($className) {
//do stuff
return new $className;
}
$class = getClass("className");
That works in its simplest format, but of course classes and functions have arguments sent to them and this poses a problem, as the possibilities for the different arguments are endless.
I thought there'd be an easy way around this using func_get_args. However I don't know how to then send the arguments to the function or class other than in an array. So the only solution i've been able to come up with is to just accept a single argument as an array and then use the list function, e.g:
PHP Code:
class className {
public function __construct($args) {
list($this->option1, $this->option2, $this->option3) = $args;
}
}
function getClass() {
$args = func_get_args();
//The class name should be the first paramater and we don't want to send it to the class.
$className = array_shift($args);
Sorry I did the second snippet of code and totally forgot to finish what I was saying.
The problem I have with this solution is that it makes things slightly messier as i'd have to check for required arguments rather than the function already expecting it.
What i'm actually wanting to do is check for existances of an object first. For instance, I've found I may sometimes call the object for a product twice when I try to get all the cart items and all the products on a certain page.
So in this instance, the function would check if it exists and if so i'd return the existing object. That way I don't do sql queries multiple times and if I modify the product the old data won't still be present in the other instance of the object.
Or you might want to create some sort of collection object (registry pattern?) to store each such object, and provide it with the necessary logic to control duplication. This way your more specific objects would not need to be singletons, with the testing and re-usability issues that entails. (Even if you decide to make the containing "collection" object a singleton, at least you are limiting that pattern to just that one class.)
"Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
~ Terry Pratchett in Nation
Woops I read your reply the other day, then started playing with it again and forgot to reply!
I think what you've described is basically what i'm trying to do. I've got a "cache" class and the idea is to pass each class call through this function which checks to see if it's already stored in the cache class.
What you described doesn't really solve my problem of passing the right arguments through to the class again if I do need to create it.
This is the best I could think of, but I can't say I'm crazy about it. It requires that you use a recent enough version of PHP that you can instantiate a class via a variable for the class name. (IIRC, you can't do that before 5.1 or 5.2?)
PHP Code:
<?php interface iParams { public function params($argArray); }
class Foo implements iParams { public $var1; public $var2; public function __construct($var1=null, $var2=null) // all args optional { $this->var1 = $var1; $this->var2 = $var2; } public function params($argArray) { if(!is_array($argArray) or count($argArray) != 2) { throw new Exception("Must be 2 args"); } $this->var1 = $argArray[0]; $this->var2 = $argArray[1]; } }
class MyCache { public function getClass() { if(func_num_args() == 0) { throw new Exception("no class name"); } $args = func_get_args(); $className = array_shift($args); if($this->objNotYetInstantiated($className)) { $this->$className = new $className; if(is_a($this->$className, 'iParams') && !empty($args)) { $this->$className->params($args); } } return $this->$className; } private function objNotYetInstantiated($class) { return(!isset($this->$class)); } }
"Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
~ Terry Pratchett in Nation
Bookmarks