/a href="http://www.stubbles.org/">
![]() /a href="http://www.stubbles.org/">
![]() Saturday, March 24. 2007
My wishlist for PHP6, pt4: static initializers
I'm using static properties quite a lot, often in combination with static classes. This is, where I often encounter a major drawback in PHP. It is not possible to write code like this:
<?php
class Foo {
private static $bar = new Bar();
public static function getBar() {
return self::$bar;
}
public static function modifyBar() {
self::$bar->doSomething();
}
}
?> In PHP. it is not possible to initialize a property with an object. As long as a constructor is involved, this is no problem, as the workaround is to initialize this properties in the constructor: <?php
class Foo {
private $bar;
public function __construct() {
$this->bar = new Bar();
}
}
?> But how could this be solved, when you never create an instance of Foo but only use static method calls?
I propose a new feature, we implemented in the /a href="http://www.stubbles.org/exit.php?url_id=150&entry_id=15" onmouseover="window.status='http://www.stubbles.net/wiki/Docs/Classloader#Staticinitializing';return true;" onmouseout="window.status='';return true;" title="Static nitializing in Stubbles">Stubbles class loader and has been shamelessly ripped from the /a href="http://www.stubbles.org/exit.php?url_id=151&entry_id=15" onmouseover="window.status='http://xp-framework.info/xml/xp.en_US/news';return true;" onmouseout="window.status='';return true;" title="XP Framework blog">XP framework. If you need to initialize some properties with objects and are developing with Stubbles, you only need to implement a method called __static() in your class. If your class is loaded by the Stubbles class loader, it will check, whether this method has been implemented and call it. As every class is only loaded once, this enables you to add code to your class, that is also only executed once, if the class is imported into your application.
To make the previous example work, it has to be modified like this: <?php
class Foo {
private static $bar;
public static function __static() {
self::$bar = new Bar();
}
public static function getBar() {
return self::$bar;
}
public static function modifyBar() {
self::$bar->doSomething();
}
}
?> This resembles the /a href="http://www.stubbles.org/exit.php?url_id=152&entry_id=15" onmouseover="window.status='http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html';return true;" onmouseout="window.status='';return true;" title="Static intializer blocks in Java">static {} block, that you can embed in Java classes, and we think, that it would be useful to have something similar in PHP. I don't care, whether PHP6 introduced a new /a href="http://www.stubbles.org/exit.php?url_id=153&entry_id=15" onmouseover="window.status='http://php.net/oop5.magic';return true;" onmouseout="window.status='';return true;" title="Magic methods in PHP">magic method or a static {} block like Java, I just want to be able to execute code after loading a class. ![]() Trackbacks
Trackback specific URI for this entry
No Trackbacks
![]() Comments
Display comments as
(Linear | Threaded)
Why not just put a myclass::initialize() just below the definition of the class?
While this does work, it's a workaround, just like our solution. I'd prefer having a standard for this. It will make it easier to understand, which code gets executed after the class had been loaded.
Because it's not possible if myclass::initialize() is private. And it should be private if we don't want someone from the outside of the class to call it second time, and don't want to bother him also with that function, which is private matter of the class.
Singleton anyone?
A singleton is an instance of a class, that's something different than static class members. Trust me, I'm very familiar with this pattern, I'm the author of PHP Design Patterns by O'Reilly.
Static initializers can be used to implement though, if you do not care about lazy initialization of the instance.
I use the same trick in my code. I agree, this would be a cool feature. Personally, I have named your __static() ... __static_construct(), because I also have a __static_destruct() !
When existing, my __static_destruct() is called at the very end of the script. Maybe an other idea for your wishlist ?
What are you doing inside a static destructor? Can you give some examples where it is useful for you? I can not see any useful examples for this.
In some cases, I use static classes like a singleton. In these cases, __static_construct and __static_destruct have exactly the same interest as in instanciable classes.
For example, I have a class in charge of some translation mechanism. During script execution, I consume its services through TRANSLATE::get($whatever). TRANSLATE::__static_destruct() is called at the end of the script and its job is to populate a cache of translations : the static class internally stores every new translation being made during execution. At the end, they are all stored for caching by __static_destruct, for later speedup.
You shouldn't be using statics that much because they aren't really object orientated i.e. you get no polymorphism, you have to code to concrete classes rather than interfaces and there's no instance to pass to another object for something.
Very often all this leads to the ignorance of the single responsibility principle and maintenance problems.
I do think that static methods can also be considered as instance methods, in which way a static class is a singleton object itself, with specific responsibilities. Before PHP 5.2 you can declare abstract static methods, but since 5.2 it was removed. PHP is dynamic, not static as C++ or Java, if possible, why not allow abstract static methods?
Static classes can be very useful as helpers to objects by aggregating useful functions together around common class variables, without singletons & objecs, though the registry pattern comes close.
At least that's how it seems I'm using them more & more. Really a refactoring of php4 library functions around common themes. A bit javascriptish at times. S
Many language constructs aren't object orientated (in your sense), but are useful additions.
Yes, there's no instance, but you don't need any. It's a class's "meta-data" and "meta-methods" (relating to the whole class itself, not concrete objects). How does it lead to the ignorance of the single responsibility principle and maintenance problems? Static data are useful to set something "globally for all objects of a clas" [e.g. reference count, current date, last used database ID etc.]. Without static data you have to repeat meta-data in every instance, which is redundant, and you have to synchronize it manually over all instances. And THAT is a maintenance problem! ![]()
Hi,
I've done the same with my phpoof class library, but I've found a problem. Tell me if you've found a solution for it ![]() What I do is, in the __autoload() function, call $class::__static() if method_exists( $class, '__static' ) is true (php5.3 only...) But... If I've defined a __static method in a parent class, and I'm statically calling (thus including) a subclass, then the __static method of the parent will be called twice (once when it's included), and another time if the subclass doesn't have its own __static method. Do you follow me? Try it with this code below class ParentClass { public static function __static() { printf( "Statically initialazing %s\n", get_called_class() ); } } class SubClass extends ParentClass { public static function hello() { echo "Hello\n"; } } SubClass::hello(); That's not desireable at all... Static initialization is only supposed to happen once (Depending on what you do on your __static() method, most probably it won't be harmful, but it'll definitely affect performance)
too bad, too bad, I already requested that in 2001...
hidden class; "self" instance; static initializer... ![]() ![]() /a href="http://www.stubbles.org/">Frontpage - /a href="#topofpage">Top level ![]() Powered by /a href="http://www.s9y.org">s9y - Design by /a href="http://www.mistralys.com/">Mistralys |
/a href="http://stubbles.net">![]() ![]() ![]() |