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

Reply via email to