RE: [PHP-DEV] [patch] Late static bindings (LSB)
| From: | Dmitry Stogov | Date: | Mon, 01 Oct 2007 11:25:23 +0000 |
| Subject: | RE: [PHP-DEV] [patch] Late static bindings (LSB) | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-32512@lists.php.net to get a copy of this message | ||
Hi Robin,
Thank you for catching this issue.
static:: make no sense in compile-time constants.
I've just forbidden it there.
Thanks. Dmitry.
> -----Original Message-----
> From: Robin Fernandes [mailto:rewbs.soal@gmail.com]
> Sent: Friday, September 28, 2007 6:45 PM
> To: internals@lists.php.net
> Cc: Stanislav Malyshev; Baptiste Autin; Zoe Slattery; Dmitry
> Stogov; Marcus Boerger; Lukas Kahwe Smith; Michael Lively;
> Etienne Kneuss; Andi Gutmans
> Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
>
>
> 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 <diogin@gmail.com> 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 <stas@zend.com> 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
> > > stas@zend.com http://www.zend.com/
> > > (408)253-8829 MSN: stas@zend.com
> > >
> > > --
> > > 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
> >
>