How can I call a static method on a variable class?

Jelle Spekken picture Jelle Spekken · Mar 13, 2009 · Viewed 56.8k times · Source

I'm trying to make some kind of function that loads and instantiates a class from a given variable. Something like this:

<?php
function loadClass($class) {
  $sClassPath = SYSPATH."/classes/{$class}.php";
  if (file_exists($sClassPath)) {
    require_once($sClassPath);
    $class = $class::getInstance();
  }
}
?>

If I use it like this:

<?php
  loadClass('session');
?>

It should include and instantiate the session class.

BTW: the static getInstance function comes from this code:

<?php
  function getCallingClass() {
    $backtrace = debug_backtrace();
    $method    = $backtrace[1]['function'];
    $file      = file($backtrace[1]['file']);
    $line      = $file[($backtrace[1]['line'] - 1)];
    $class     = trim(preg_replace("/^.+?([A-Za-z0-9_]*)::{$method}\(.*$/s", "\\1\\2", $line));

    if(! class_exists($class)) {
      return false;
    } return $class;
  }

  class Core {

    protected static $instances = array();

    public static function getInstance() {
      $class = getCallingClass();

      if (!isset(self::$instances[$class])) {
        self::$instances[$class] = new $class();
      } return self::$instances[$class];
    }

  }

?>

The thing is that right now the way to use the functions in a class is this:

<?php
  $session = session::getInstance();
?>

But now I want to build that into a function so that I never again have to use that line of code. I just say loadClass('session'); and than I can use $session->blablablafunction();

Answer

talentedmrjones picture talentedmrjones · Jun 25, 2010

Calling static functions on a variable class name is apparently available in PHP 5.3:

Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0

http://php.net/manual/en/language.oop5.static.php

Could definitely use that right now myself.

Until then you can't really assume that every class you are loading is designed to be a singleton. So long as you are using < 5.3 you'll have to just load the class and instantiate via the constructor:

function loadClass($class) {
  $sClassPath = SYSPATH."/classes/{$class}.php";
  if (file_exists($sClassPath)) {
    require_once($sClassPath);
    $class = new $class;
  }

}

OR

Just load the class without creating an object from it. Then call "::getInstance()" on those meant to be singletons, and "new" on those that are not, from outside of the loadClass() function.

Although, as others have pointed out earlier, an __autoload() would probably work well for you.