On Fri, Jul 5, 2024 at 2:23 PM Dusk <[email protected]> wrote:
>
> To that end - consider the following. Let's say that two different files
> in your project import different versions of package Foo. Foo contains a
> definition of the FooBar class, and contains functions which return that
> object.
>
> 1) If $foobar is one of those FooBar objects, what does $foobar::class
> return?
Depends on where it was imported to. The current system ALWAYS imports to
the root namespace. This new system can import there, but also to another
namespace. This was outlined in my previous email.
For @A\Foo\FooBar the import will put FooBar at \A\Foo\FooBar, and that's
what class will return. @B\Foo\FooBar will bind it to \B\Foo\FooBar and
that will be the return of the class constant within the class.
> Is it the same as the fully qualified name of FooBar (e.g. "Foo\FooBar")?
> Does the result differ depending on what file contains that code?
>
Again, it depends on which package namespace the code was imported into.
Foo\FooBar isn't a fully qualified name even in current PHP. Fully
qualified names start with \, so the fully qualified name is \Foo\FooBar
provided it was included into the root namespace.
>
> 2) What happens if you try to pass that string back to something like new
> $class() or construct a ReflectionClass for it? Does that depend on the
> location of the call? What if the call is through something like
> PDO::FETCH_CLASS which occurs within the runtime?
>
Again, which package are we in?
>
> 3) Within Foo, would it be true that if $x = new FooBar(), then $x::class
> === FooBar::class?
Yes.
> Does this differ outside Foo (with an appropriately qualified name for
> FooBar)?
>
That's tricker, because the namespace matters in a way that it doesn't
matter now. Given an import mapping of "@A\FooBar" then
namespace A;
$x = new FooBar();
$x::class === FooBar::class // true, however...
echo $x::class // \A\Foo\FooBar
That holds true even if FooBar's declaration file doesn't invoke any
namespace.
>
> 4) If those two files both create FooBar objects of their respective
> versions, what happens if you try to pass one of those objects to a
> function in the file using the "wrong" version of Foo? Does it pass type
> checks, and what happens if it does? If not, how does the check fail?
>
Each package has its own Foo\FooBar. They won't be interoperable even
though they arise from the same code. If they should be or need to be
interoperable then PHP will have to gain a notion of package beyond what's
been scoped out here.
> 5) What shows up in the output of functions like get_declared_classes()?
> Are there multiple instances of FooBar in there for each version? How are
> they distinguished from one another?
You'll get
\A\Foo\FooBar
\B\Foo\FooBar
If you also directly load Foo\FooBar into the root namespace using the
composer autoloader you could also see \Foo\FooBar