Hi Anthony.

   This issue that has plagued me in the past, specifically with the use of
traits:

Error:  http://3v4l.org/VFguK
OK:     http://3v4l.org/73b86

Although when combined with opcache does causes very confusing behaviour, I
do worry that removing the error altogether may make it worse for
developers.

Take this example with constants:

namespace Biz {
    const Bar = 41;
}

namespace Foo {
    const Bar = 42;
}

namespace Foo {
    use const Biz\Bar;
    echo Bar;
}

// Fatal error: Cannot use const Biz\Bar as Bar because the name is already
in use

http://3v4l.org/0pRZk

An error here is far more useful that trying to exhibit the behaviour of
when the namespaces are declared in reverse order:

namespace Biz {
    const Bar = 41;
}

namespace Foo {
    use const Biz\Bar;
    echo Bar;
}

namespace Foo {
    const Bar = 42;
}

// 41

http://3v4l.org/E4PFX

I suppose the question here is; Does the declaration order matter?
Personally I think it should.


/@leedavis81



On Thu, Mar 5, 2015 at 7:40 PM, Anthony Ferrara <ircmax...@gmail.com> wrote:

> All,
>
> Currently, use has a few error cases that are rather fragile. For example:
>
>
> namespace Biz {
>     class Bar {};
> }
>
> namespace Foo {
>     use Biz\Bar;
>     $a = new Bar;
>     var_dump($a);
> }
>
> namespace Foo {
>     class Bar {};
> }
> http://3v4l.org/IPTiQ
>
> That works 100% of the time, on 5.3.0 -> present.
>
> But if we change the order of the two Foo blocks:
>
> namespace Biz {
>     class Bar {};
> }
>
> namespace Foo {
>     class Bar {};
> }
>
> namespace Foo {
>     use Biz\Bar;
>     $a = new Bar;
>     var_dump($a);
> }
>
> http://3v4l.org/KlXUq
>
> We get a Fatal error that "Cannot use Biz\Bar as Bar because the name
> is already in use.
>
> Basically, zend_compile.c is doing a check of the current symbol table
> to see if the class is already defined when doing the use.
>
> This is problematic not just for the example above, but when combined
> with opcache. Opcache nulls out the symbol tables for file
> compilation. So that means that file inclusion order matters when it's
> disabled, but not when it's enabled.
>
> This was discovered last night by Drupal 8 developers, when they
> noticed that some developers claimed fatal errors, while they weren't
> able to reproduce. After some debugging, it turned out that disabling
> opcache caused the fatal errors. It was because of this symbol table
> change.
>
> The error is fragile. And IMHO it's not really protecting anything
> significant, since it's clear within the file what each symbol refers
> to (you need to look at use declarations for that anyway).
>
> So, I created a PR to remove this error:
> https://github.com/php/php-src/pull/1149
>
> Note that there is no BC break here, as it's removing an error condition
> today.
>
> This results in a weird edge case (which is 100% valid, but feels odd):
>
> <?php
> class Test {}
> use Bar\Test;
> var_dump(new Test); // class(Bar\Test)
>
> That's perfectly valid, if not a bit weird.
>
> The reverse would error mind you:
>
> <?php
> use Bar\Test;
> class Test {}
>
> Because you've already defined the symbol Test in the file.
>
> To get around this, I've created another PR with a BC break, adding a
> compile error if code comes before `use`:
> https://github.com/php/php-src/pull/1150
>
> This requires use to immediately follow namespace declarations:
>
> namespace Foo {
>     use Bar; //valid
> }
> namespace Bar {
>     use Foo; //valid, second namespace in file
> }
> namespace Baz {
>     echo "Hi!";
>     use Foo; // Invalid
> }
>
> This did break approximately 30 internal tests, but they were all
> testing this specific code path (or bugs related to it).
>
> What are your thoughts about both PRs? The first seems like a clear
> win, the second is a nice cleanup but also a bit of a change to
> behavior... I'm not sure if an RFC is required for either, but if
> people want one (for both, for one, etc) I can draft something up
> quickly.
>
> Remove symbol check: https://github.com/php/php-src/pull/1149
> Pin use to top: https://github.com/php/php-src/pull/1150
>
> Thanks
>
> Anthony
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

Reply via email to