Sorry to persist with this, but I think it could be really useful to
clarify the meaning of static:: outside of method bodies...
particularly since parent:: and self:: can already behave very
strangely in such scenarios (see
http://news.php.net/php.internals/32443 ).
For example, I find the following behaviour with the current patch
counter-intuitive:
<?php
// NOTE: X is not related to A.
class X {
const MY_CONST = "I am completely unrelated to class A.";
static function createA() {
new A; // triggers initialiser evaluation
}
}
class A {
const MY_CONST = "const A";
public $p = static::MY_CONST;
static function getInstance() {
return new A;
}
}
// First instantiate A inside X. This causes A's properties'
// default values to be evaluated within X's scope.
X::createA();
// Now that A's default values have been evaluated,
// behaviour is as if any new instance of A treats
// the occurrence of static:: on line 12 to mean X.
// Instantiate A inside A:
$a = A::getInstance();
var_dump($a->p); // has value of X::MY_CONST.
// Instantiate A at global scope:
$a = new A();
var_dump($a->p); // has value of X::MY_CONST.
?>
Actual output:
string(37) "I am completely unrelated to class A."
string(37) "I am completely unrelated to class A."
Some thoughts:
- static:: could simply be forbidden in all class property/constant
default values.
- Any occurrences of static:: in instance property default values
could behave as if they were in the constructor, but be forbidden in
static property and constant initialisers.
- Other ideas?
Also, there are some questions around reflection. All of the following
A::reflect*() calls cause a fatal error like:
PHP Fatal error: Undefined class constant 'MY_CONST' in %s on line %d
<?php
class A {
const MY_CONST = "const A";
const C1 = static::MY_CONST;
static function f($a = static::MY_CONST) {
return $a;
}
static function f2() {
static $x = static::MY_CONST;
}
static function reflectConst() {
$rc = new ReflectionClass('A');
var_dump($rc->getConstant('C1'));
}
static function reflectArg() {
$rm = new ReflectionMethod('A::f');
$rps = $rm->getParameters();
var_dump($rps[0]->getDefaultValue());
}
static function reflectStat() {
$rm = new ReflectionMethod('A::f2');
var_dump($rm->getStaticVariables());
}
}
A::reflectConst(); // fatal error
A::reflectArg(); // fatal error
A::reflectStat(); // fatal error
?>
Is this desirable? One could argue that the reflection calls emanate
from A::, so static:: could be resolved accordingly. This test case
suggests that static:: is in fact being bound to the ReflectionClass
class itself (since ReflectionClass::IS_FINAL===64) :
<?php
class A {
const IS_FINAL = "This string is not integer sixty-four";
const C1 = static::IS_FINAL;
}
$rc = new ReflectionClass('A');
$rc->getConstant('C1'); // trigger evaluation of A::C1
var_dump(A::C1);
?>
Actual output:
int(64)
Kind regards,
Robin
On 27/09/2007, Jingcheng Zhang <[EMAIL PROTECTED]> wrote:
> Hello,
> static methods seem exactly like dynamic binded methods now, is there
> any chance that "abstract static function" being restored from E_STRICT
> limitation? Currently it is allowed in interfaces, but forbidden in abstract
> class, I don't know why php implements "static method" in this way, this
> seems strange.. Thanks!
>
> On 9/27/07, Stanislav Malyshev <[EMAIL PROTECTED]> wrote:
> >
> > > So, if I understand you well, Stanislas, you are personally not much
> > into
> > > "static::" but more into making that sort of code working :
> > >
> > > interface iC {
> > > public $structure;
> > > }
> > > abstract class A implements iC {
> > > public function display() {
> > > echo self::$structure;
> > > }
> > > }
> > > class B extends A {
> > > static public $structure = "This is a string.";
> > > }
> > > $b = new B();
> > > $b->display();
> >
> > No, I don't think we should make interfaces with variables, I'm just
> > telling that the code before had API that not allowed correctly enforce
> > its requirements.
> > --
> > Stanislav Malyshev, Zend Software Architect
> > [EMAIL PROTECTED] http://www.zend.com/
> > (408)253-8829 MSN: [EMAIL PROTECTED]
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: http://www.php.net/unsub.php
> >
> >
>
>
> --
> Best regards,
> Jingcheng Zhang
> Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University
> P.R.China
>
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php