PHP late static binding

Why is so late and static this PHP binding ?

A static method can be used as factory, a way of generating instances of the containing class.
See the following example:

abstract class BaseObject{
	public static function create(){
		return new self();
	}
}

class User extends BaseObject{}

class Document extends BaseObject{}

Document::create();

Running this code will give:

Fatal error: Cannot instantiate abstract class DomainObject in ....

Here self refers to the context of resolution, not to the calling context. So self resolves to BaseObject, the place where create() is defined, and not to Document, the class on which it was called. PHP 5.3 introduced a concept called late static bindings and created a new keyword static.
Static is similar to self, except that it refers to the invoked rather than the containing class. So now I can take advantage of my inheritance relationship in a static context:

abstract class BaseObject{
	public static function create(){
		return new static();
	}
}

class User extends BaseObject{}

class Document extends BaseObject{}

var_dump(Document::create());
// this function will print: object(Document)#1 (0) {}

Like self and parent, static can be used as an identifier for static method calls, even from a non-static context.

Let’s change the previous sample:

abstract class BaseObject {
	private $group;
	public function __construct() {
		$this->group = static::getGroup();
	}
	public static function create() {
		return new static();
	}
	static function getGroup() {
		return "default";
	}
}

class User extends BaseObject {}

class Document extends BaseObject {
	static function getGroup() {
		return "document";
	}
}

class SpreadSheet extends Document {}

print_r ( User::create () );
print_r ( SpreadSheet::create () );

The constructor of the BaseObject class uses the static keyword to invoke a static method: getGroup(). BaseObject provides the default implementation, but Document overrides it.
Here’s the output:

User Object
(
    [group:BaseObject:private] => default
)
SpreadSheet Object
(
    [group:BaseObject:private] => document
)

email-newsletter

Dev'Letter

Professional opinion about Web Development Techniques, Tools & Productivity.
Only once a month!

Any suggestion on what to write next time ? Submit now

Opinions

avatar
550
  Subscribe  
Notify of

Related Posts