Thursday, March 22, 2007

PHP 5 developers teach us what does static keyword mean (and this is a feature!)

PHP 5 introduced a "new" keyword called static.
You can read here what does this keyword mean when it's applied to one method.

As You can read in documentation page
Declaring class members or methods as static makes them accessible without needing an instantiation of the class. A member declared as static can not be accessed with an instantiated class object (though a static method can).

They put last tiny point inside brackets as it's not a really important point to analize!

As You know, with PHP4 every method should be used as static one.
The difference between PHP 4 and PHP 5 seems to be this one:
The big difference between php 4 and php 5 is that a method declared as "static" does not have $this set. You'll get a fatal error, in fact, if you try to use $this in a static method.

Well ... static method cannot have a $this reference inside its scope but every static method is inherited into every instance ... this is absolutely hilarious:

  1. You can't call with the same name two different methods (one static, for class and one metod for instances)

  2. You can't overload manually instance method

  3. Static methods are inherited while static parameters cannot be used from instances

  4. You can't use $this reference even if You're calling method from an instance (wow, it's really OO)



To solve PHP 5 static method logic You have to forget static keyword.

class StaticString {
private $content = '';
function __construct($content){
$this->content = $content;
}
// I need different methods, not static one inherited!!!
function write($what = null){
echo func_num_args() === 0 ? $this->content : $what->get(), '
';
}
function get() {
return $this->content;
}
}

StaticString::write(new StaticString('static'));
$test = new StaticString('instance');
$test->write();

The above example shows You how to "solve" static inheritance problems, based on sent arguments (then it's a fake method overload) but shows obviously an E_STRICT notice.

So, at this point, we need a workaround to make a language feature "less buggy and more featurely" ... but static keyword shouldn't be implemented if the diference is only that you can't use instance reference inside one of these method.

This is another example, based on Singleton pattern:

class Singleton {

static private $instance;
static private $init = false;

public final static function instance(){
if(!Singleton::$init) {
Singleton::$instance = new Singleton();
Singleton::$init = true;
}
return Singleton::$instance;
}
}

$test = Singleton::instance();
var_dump($test->instance() === $test);

WoW! ... my Singleton instance inherits Singleton pattern, it's amazing!

Obviously, C# and other program languages doesn't assign static class methods into instances ... and the reason is:
If you are wanting absolutely "perfect" OO, there are plenty of other languages that will provide exactly the straightjacket and punishment you desire. If you want to code efficient, easy to maintain, working programs, use PHP.

To code efficient, easy to mantain I need a clear Object Oriented logic ... and if You're thinking about C++ there's a little difference ...

C++ instances inherit static methods and static parameters too but the big difference is that if you don't declare a class method as static, You can't use them as static method (and You can't use parameters too).

static method and public (instance) one are two different things (as you know) ... but hey, cellog gives me a fantastic, "pure OO way", example to solve my debug problem

class ExampleClass {

public $StaticExample;

public final function __construct(){
// bye bye public *parameter*
$this->StaticExample = create_function('$never', 'return "welcome PHP5
ambiguity";');
}

public final static function StaticExample(){
echo "StaticExample", "<br />";
}
}

$test = new ExampleClass();
ExampleClass::StaticExample();
exit($test->StaticExample());

That's not portable, not scalable ... absolutely a bad solution ... but it could be simply solved with this code

call_user_func_array(get_class($a), 'method', $args);

And "WoW" again! .. that's what I call OOP!!!

Thank you PHP 5 developers to introduce static methods, I hope PHP 6 will be more Object Oriented and less ambiguous than version 5.

Best regards!

[edit]
This is my bug report ... pardòn, bogus report:
http://bugs.php.net/bug.php?id=40886

No comments:

Post a Comment