First of all, let's not call this 'magic'.
Static initializers aren't any more magical that object constructors.
johannes@php.net wrote:
Adding an __init method as you wish will just add complexity and gain very little.
<?php
class A {
public function __init() { echo CLASS; }
}
class B extends D {
public function __init() { echo CLASS; }
}
class C {
public function __init() { echo CLASS; }
}
class D {
public function __init() { echo CLASS; }
}
class E {
public function __init() { echo CLASS; }
}
?>
What should this print? ABCDE?
I don't see any 'complexity' here.
Correct answer is ADBCE, because subclasses might rely on something
that happens in superclass'es initializer. So superclass initializer
should definitely run first.
Now for a second game: What does the following script print?
<?php
echo "A";
class foo { static function __init() { echo "B"; } }
echo "C";
?>
ABC? ACB? BAC? I guess the later as the code next to A or C might depend
on the class already.
And what if I put some echos in my autoload function and make foo
implement A B C and D?
What's that gonna print? And why should I care?
As long as my initializer runs before this class is "used" (i.e.
before I create an instance or call any static methods or variables),
it makes no difference to me when __init() is called.
Because anything __init() does should be contained to the class itself
(or the parent), and should not be relying on, or changing anything in
the global scope.
Sure, you can put your echos there, just like you can put echos in
your autoload functions, or your constructors... It doesn't sound like
a good design choice to me, but it's your code.
But hey, here's an idea. Let's drop class autoloading 'magic' as well,
because it has all the same 'problems' that you've just described.
It loads things at 'completely arbitrary' times, it's complicated, and
it surely makes reading code 'too hard'. And the gains are 'very
little', anyway.
You can always load your classes manually with a bunch of require
statements, right?
hey, here's an idea. Let's drop class autoloading 'magic' as well,
because it has all the same 'problems' that you've just described.
It loads things at 'completely arbitrary' times, it's complicated, and
it surely makes reading code 'too hard'. And the gains are 'very
little', anyway.
You can always load your classes manually with a bunch of require
statements, right?
It is trickier than autoloading because __init() tries to blur the lines
between the compile and execute stages if I read your original email
correctly. And we have some magic in the compiler that tries to optimize
things and resolve as much of the inheritance chain as possible at
compile-time to the point where ZEND_FETCH_CLASS opcodes are NOP'ed
away(*). I suppose this could still hang off of the the initial
ZEND_FETCH_CLASS for a class, but it would definitely get tricky to
determine when this would happen.
(*) http://lxr.php.net/xref/PHP_5_4/Zend/zend_compile.c#4444
-Rasmus