tags:

views:

54

answers:

2

I want a class property to be reference to another class, not its object and then use this property to call the class's static methods.

class Database {
    private static $log;

    public static function addLog($LogClass) {
        self::$log = $LogClass;
    }

    public static function log() {
        self::$log::write(); // seems not possible to write it like this
    }
}

any suggestions how i can accomplish this?

cause i have no reason making them objects, i want to use the classes for it.

+2  A: 

Use the call_user_func function:

class Logger {
    public static function write($string) {
        echo $string;
    }
}

class Database {
    private static $log;

    public static function addLog($LogClass) {
        self::$log = $LogClass;
    }

    public static function log($string) {
        call_user_func( array(self::$log, 'write'), $string );
    }
}

$db = new Database();
$db->addLog('Logger');
$db->log('Hello world!');
Rodin
+1  A: 

Since you're seemingly only interested in one specific method/function (without further contracts/interfaces) you can write the code in a way that it doesn't matter whether it's a static method or an object method (...hm, object method...that doesn't sound right, what's the right name...) or a simple function.

class LogDummy {
  public static function write($s) {
    echo 'LogDummy::write: ', $s, "\n";
  }
  public function writeMe($s) {
    echo 'LogDummy->writeMe: ', $s, "\n";
  }
}

class Database {
  private static $log=null;

  public static function setLog($fnLog) {
    self::$log = $fnLog;
  }

  public static function log($s) {
    call_user_func_array(self::$log, array($s));
  }
}

// static method
Database::setLog(array('LogDummy', 'write'));
Database::log('foo');

// member method
$l = new LogDummy;
Database::setLog(array($l, 'writeMe'));
Database::log('bar');

// plain old function
function dummylog($s) {
  echo 'dummylog: ', $s, "\n";
}
Database::setLog('dummylog');
Database::log('baz');

// anonymous function
Database::setLog( function($s) {
  echo 'anonymous: ', $s, "\n";
} );
Database::log('ham');

prints

LogDummy::write: foo
LogDummy->writeMe: bar
dummylog: baz
anonymous: ham
VolkerK
object method sounds fine to me, but you could call it an instance method, too
Gordon