I managed to solve this problem in my own framework, by using a little class I call "this"
PHP Code:
/**
* Helper class for working with static method calls
*
* @package library
*/
class this {
/**
* Returns the name of the class that called 'this'
*
* @return string
*/
function class_name() {
$trace = debug_backtrace();
foreach($trace as $call) {
if (isset($call['class']) && $call['class'] != __CLASS__) {
return $call['class'];
}
}
return false;
}
/**
* Returns an array containing all the variables defined in the calling class
*
* @return array
*/
function get_vars() {
return get_class_vars(this::class_name());
}
/**
* Returns the value of a particular variable in the calling class. Returns
* null if it doesn't exist
*
* @return mixed
*/
function get_var($var_name) {
$vars = this::get_vars();
if (isset($vars[$var_name])) {
return $vars[$var_name];
} else {
return null;
}
}
/**
* Returns true if the variable exists in the calling class.
*
* @return bool
*/
function var_exists($var_name) {
$vars = this::get_vars();
return isset($vars[$var_name]);
}
/**
* Returns an array of all the methods defined in the calling class
*
* @return array
*/
function get_methods() {
return get_class_methods(this::class_name());
}
/**
* Returns true if the method exists in the calling class.
*
* @param string $method_name
*/
function method_exists($method_name) {
$methods = this::get_methods();
return in_array($method_name, $methods);
}
/**
* Calls a static function in the calling class. All the parameters
* are passed to the function, as in call_user_func
*
* @param string $method_name
* @param mixed $args,...
* @return mixed
*/
function call($method_name) {
$args = func_get_args();
array_shift($args);
return call_user_func_array(array(this::class_name(), $method_name), $args);
}
/**
* Calls a static function in the calling class. The args array
* is passed to the function, as in call_user_func_array
*
* @param string $method_name
* @param array $args
* @return mixed
*/
function call_array($method_name, $args) {
return call_user_func_array(array(this::class_name(), $method_name), $args);
}
}
and a little test case
PHP Code:
class ThisTester extends UnitTestCase {
var $test = 'hello';
function test_all() {
$this->assertEqual(this::class_name(), __CLASS__);
$this->assertEqual(this::get_var('test'), 'hello');
$this->assertTrue(this::call('call_me'));
$this->assertEqual(this::call('call_me', 'test'), 'test');
$this->assertEqual(this::call('math', 1, 10, 100), 111);
$this->assertEqual(this::call_array('math', array(2, 20, 200)), 222);
$this->assertTrue(this::method_exists('run'));
$this->assertFalse(this::method_exists('foo'));
}
function call_me($param = true) {
return $param;
}
function math($one, $two, $three) {
return $one + $two + $three;
}
}
Usage should be clear, but here's some code from my finder method
PHP Code:
// find a single id
$options['conditions'] .= this::call('table_name').".".this::get_var('id_field')." = '".$ids[0]."'";
$result = this::call('find', 'all', $options);
Say what you will about using this kind of hack, "this" works
Bookmarks