Zoop Auth Usage :: Issue with Late Static Binding

I am upgrading the auth component for the 2.0 release.

Goals.
1. Easy to use.
2. Extendable.
3. Support multiple instances in one application
4. Support multiple backends (db, doctrine, yaml, etc).

Since PHP 5.2 and below don't support late static binding, I am struggling with how to accomplish both 1 and 2 (and 3).

The possible syntax's are

auth::requireUser("steve");

or
auth::gi()->requireUser("steve");

or
$a = new auth();
$a->requireUser("steve");

The first one is the best, but without late static binding, isn't extendable (and consequently cannot have multiple instances).

The next two both use objects rather than classes. They accomplish 2 & 3 fine, but aren't as nice a syntax. I prefer the singleton method between the two, just because it is shorter.

5.3 will have late static binding and was scheduled to be released this month, but looking at the php site, it seems that they are a bit behind schedule.

Do we commit to always using the singleton method?
Is there a way to place a hack in to permit the first approach when using php_version < 5.3 ?

In short this is the issue.
I want object oriented code with classes. After 5.3 I can just call static::_getName(); and it will return the desired name.

Scenario: auth as a base class

The point of extending this would be to supply a different config (and potentially driver) for different aspects of an application. For instance for the admin section of your site you may want to hard code in yaml the users. For the general users, you may want another instance using doctrine.

class auth
{
    public static $configBase = "zoop.auth";
 
    function className() {
        return __CLASS__;
        return "auth";
    }
 
    function _getDriver() {
        global $zoop;
        $backend = self::getConfig('backend');
        $name = "auth_driver_" . $backend;
        $zoop->addInclude($name, ZOOP_DIR . "/auth/drivers/$backend.php");                                                                                                                                
        return new $name();
    }   
 
    function testDriver() {
        $drv = self::_getDriver();
        return $drv->test();
    }   
 
    function getConfigBase() {
        return 'zoop.auth';
    }
 
    /**
     * returns the config value for the auth component.
     *
     * @param string $path
     * @return mixed
     */
    function getConfig($path = false) {
        if ($path) {
            $path = "." . $path;
        }
 
        return Config::get(self::getConfigBase() . $path );                                                                                                                                               
    }
 
 
...

The problem is the self::getConfig() and self::_getDriver(); calls that are all around.

Is there a way to avoid these self:: calls?

I know I provide 2 methods of accessing a configBase in the example. Neither worked properly, I was just trying to play with it.

Late static Binding

The closest thing to Late Static Binding you can do right now is possibly:

class Auth{
function staticFunc($driver, $params)
{
call_user_func(array($driver, 'staticFunc'), $params)
}
 
class AuthDriver extends Auth{
function staticFunc() {echo 'AuthDriver';}
}
 
Auth::staticFunc('AuthDriver', $params);

And since that kind of sucks, It's best to try to find ways around it. The bright side is that whatever you do, will probably not conflict with a future implementation using LSB.

john 31 Oct 2008

Static Calls

I do a lot of static calls in PHP 5.2 but you can't call the static function in your class using self you need to use the class name to call the function. Also the static function cannot access anything using $this. The self and this reference would imply that an object exists, but a static function does not need to be called via an object. Check out the sample below. Does this answer your question?

class MyClass {
 
public function MyClass() {
}
 
static function DoStatic() {
//Do Something
}
 
public function call Static() {
MyClass::DoStatic();
}
 
}

jmorant@cloud9l... 05 Nov 2008

Static Variable

I would also drop the use the static variable at the top of your class in favor of a const. A public static variable is just a const is it not?

//public static $configBase = "zoop.auth";
const configBase = "zoop.auth";
 
//Now you can use MyClass::configBase

jmorant@cloud9l... 05 Nov 2008