[PHP-DEV] [RFC] Change Directory class to behave like an opaque object

Hello internals,

I came across the Directory class while doing some code exploration of ext/standard.
This class is effectively an opaque object for Directory resources, however it doesn't behave like one, as it has existed since PHP 4.

As such, I am proposing an RFC to turn this class into an opaque object.

RFC: PHP: rfc:directory-opaque-object

Best regards,

Gina P. Banyard

On 14.09.2024 at 17:33, Gina P. Banyard wrote:

I came across the Directory class while doing some code exploration of ext/standard.
This class is effectively an opaque object for Directory resources, however it doesn't behave like one, as it has existed since PHP 4.

As such, I am proposing an RFC to turn this class into an opaque object.

RFC: PHP: rfc:directory-opaque-object

As I see it, an opaque object is an object which doesn't have any public
members. Since Directory has five public members, I wouldn't call it
opaque.

Other than that wording issue, I welcome this RFC. Thank you!

Christoph

Seems right thing to do.

I saw some usage like

final class Dir extends Directory
{
}

also did not see much in new codes Directory being extended so 8.5 sure.

Cheers.

On Sat, 14 Sept 2024 at 16:36, Gina P. Banyard internals@gpb.moe wrote:

Hello internals,

I came across the Directory class while doing some code exploration of ext/standard.
This class is effectively an opaque object for Directory resources, however it doesn’t behave like one, as it has existed since PHP 4.

As such, I am proposing an RFC to turn this class into an opaque object.

RFC: https://wiki.php.net/rfc/directory-opaque-object

Best regards,

Gina P. Banyard

On Sat, 14 Sep 2024, Gina P. Banyard wrote:

I came across the Directory class while doing some code exploration of
ext/standard. This class is effectively an opaque object for Directory
resources, however it doesn't behave like one, as it has existed since
PHP 4.

As such, I am proposing an RFC to turn this class into an opaque
object.

RFC: PHP: rfc:directory-opaque-object

I see you want to make "new Directory" not work - but wouldn't it make
more sense if that was the *prefered* way instead of using dir() ?

cheers,
Derick

On 16.09.2024 at 18:31, Derick Rethans wrote:

On Sat, 14 Sep 2024, Gina P. Banyard wrote:

I came across the Directory class while doing some code exploration of
ext/standard. This class is effectively an opaque object for Directory
resources, however it doesn't behave like one, as it has existed since
PHP 4.

As such, I am proposing an RFC to turn this class into an opaque
object.

RFC: PHP: rfc:directory-opaque-object

I see you want to make "new Directory" not work - but wouldn't it make
more sense if that was the *prefered* way instead of using dir() ?

I also thought this at first, but if Directory will replace Dir handle
resources in PHP next, it might not make too much sense, since I presume
that dir() is rarely used compared to opendir(), and I think we need to
keep opendir() and friends for a long time, anyway.

Christoph

On Monday, 16 September 2024 at 18:31, Derick Rethans <derick@php.net> wrote:

On Sat, 14 Sep 2024, Gina P. Banyard wrote:

> I came across the Directory class while doing some code exploration of
> ext/standard. This class is effectively an opaque object for Directory
> resources, however it doesn't behave like one, as it has existed since
> PHP 4.
>
> As such, I am proposing an RFC to turn this class into an opaque
> object.
>
> RFC: PHP: rfc:directory-opaque-object

I see you want to make "new Directory" not work - but wouldn't it make
more sense if that was the prefered way instead of using dir() ?

I don't have any strong preferences, but this could always be amended as a follow-up.
I don't expect anyone to instantiate Directory with new anyway as it results in a broken object.

Best regards,

Gina P. Banyard

On Saturday, 14 September 2024 at 18:48, Christoph M. Becker <cmbecker69@gmx.de> wrote:

On 14.09.2024 at 17:33, Gina P. Banyard wrote:

> I came across the Directory class while doing some code exploration of ext/standard.
> This class is effectively an opaque object for Directory resources, however it doesn't behave like one, as it has existed since PHP 4.
>
> As such, I am proposing an RFC to turn this class into an opaque object.
>
> RFC: PHP: rfc:directory-opaque-object

As I see it, an opaque object is an object which doesn't have any public
members. Since Directory has five public members, I wouldn't call it
opaque.

Eh, GMP is also "kinda" an opaque object, and I don't really have any better naming idea, so I went with what is the closest common concept we have.
But if you have any idea for better terminology, I would gladly use it.

Best regards,

Gina P. Banyard

On 17.09.2024 at 18:03, Gina P. Banyard wrote:

On Saturday, 14 September 2024 at 18:48, Christoph M. Becker <cmbecker69@gmx.de> wrote:

On 14.09.2024 at 17:33, Gina P. Banyard wrote:

RFC: PHP: rfc:directory-opaque-object

As I see it, an opaque object is an object which doesn't have any public
members. Since Directory has five public members, I wouldn't call it
opaque.

Eh, GMP is also "kinda" an opaque object,

Yeah, but this only has magic methods, while Directory already has
"proper" methods.

and I don't really have any better naming idea, so I went with what is the closest common concept we have.
But if you have any idea for better terminology, I would gladly use it.

No, I don't have a better idea, and I'm not too much concerned about
that now. Only my first reaction was: "What? Why remove the existing
methods?"

Christoph

On Saturday, 14 September 2024 at 16:33, Gina P. Banyard <internals@gpb.moe> wrote:

Hello internals,

I came across the Directory class while doing some code exploration of ext/standard.
This class is effectively an opaque object for Directory resources, however it doesn't behave like one, as it has existed since PHP 4.

As such, I am proposing an RFC to turn this class into an opaque object.

RFC: PHP: rfc:directory-opaque-object

Unless there are further comments I will be opening the vote for the RFC on Saturday.

Best regards,

Gina P. Banyard

Am 14.09.2024 um 17:33 schrieb Gina P. Banyard <internals@gpb.moe>:

I came across the Directory class while doing some code exploration of ext/standard.
This class is effectively an opaque object for Directory resources, however it doesn't behave like one, as it has existed since PHP 4.

As such, I am proposing an RFC to turn this class into an opaque object.

RFC: PHP: rfc:directory-opaque-object

While I understand the other proposed changes (although I'm always a bit wary about the wish to make more and more things final) I was wondering why you would prevent cloning?
What are the possible downsides in allowing people to get a clone of a Directory object?

Regards,
- Chris

On Tuesday, 24 September 2024 at 14:34, Christian Schneider <cschneid@cschneid.com> wrote:

Am 14.09.2024 um 17:33 schrieb Gina P. Banyard internals@gpb.moe:

> I came across the Directory class while doing some code exploration of ext/standard.
> This class is effectively an opaque object for Directory resources, however it doesn't behave like one, as it has existed since PHP 4.
>
> As such, I am proposing an RFC to turn this class into an opaque object.
>
> RFC: PHP: rfc:directory-opaque-object

While I understand the other proposed changes (although I'm always a bit wary about the wish to make more and more things final) I was wondering why you would prevent cloning?
What are the possible downsides in allowing people to get a clone of a Directory object?

Mainly because the current behaviour doesn't do a proper clone.
It still shares a common directory resource with the original object meaning that there is spooky action at a distance even thought cloning is meant to prevent this.

Best regards,

Gina P. Banyard

On Sat, 2024-09-14 at 15:33 +0000, Gina P. Banyard wrote:

Hello internals,

I came across the Directory class while doing some code exploration
of ext/standard.
This class is effectively an opaque object for Directory resources,
however it doesn't behave like one, as it has existed since PHP 4.

As such, I am proposing an RFC to turn this class into an opaque
object.

RFC: PHP: rfc:directory-opaque-object

Best regards,

Gina P. Banyard

I don't suppose we could call the Directory class something else, like
"SPLDirectory"?

You can't make a Directory with `new` (or at least you aren't supposed
to be able to), so any existing code would already get a Directory
object with `dir()` not `new Directory()`. There would be no BC break
with a rename.

Why?

It's very easy for someone that doesn't know about the Directory class
to create their own class called `Directory`, instantiate it with `new`
expecting their autoloader to pick it up, and then getting very strange
results.

The error will usually be something like, "call to undefined method
Directory::MyMethod", which makes developers go nuts, looking at their
Directory class, seeing "MyMethod" clearly defined right there, and yet
PHP claims it can't find the method. But PHP is finding the **class**
because surely, the autoloader loaded it!

What actually happened is the autoloader didn't run because the name
"Directory" is already registered. But there is no warning or error
when someone writes `new Directory();`.

Since the built-in Directory class is never instantiated by name,
nothing would break by renaming it, since it only gets created by
`dir()`.

A rename would free up the name 'Directory' so people wouldn't get
frustrated with bizarre behavior when they make their own Directory
class (which I imagine is very common).

On Wednesday, 25 September 2024 at 10:12, Nick Lockheart <lists@ageofdream.com> wrote:

On Sat, 2024-09-14 at 15:33 +0000, Gina P. Banyard wrote:
I don't suppose we could call the Directory class something else, like
"SPLDirectory"?

You can't make a Directory with `new` (or at least you aren't supposed
to be able to), so any existing code would already get a Directory
object with `dir()` not `new Directory()`. There would be no BC break
with a rename.

This is factually incorrect.
This would be a large BC break, moreover PHP "owns" the global namespace.

If you are in a namespace and attempting to instantiate a class
named Directory you will either get the namespace version of the class,
or an Error as there is no fallback to the global namespace for classes.

Otherwise, if you are in the global namespace and try to create a class
which is called Directory this would result in an Error being thrown.

Finally, people may have typed properties, or parameters with the type
Directory, renaming this would break all that code.

Best regards,

Gina P. Banyard

On Tuesday, 24 September 2024 at 13:25, Gina P. Banyard <internals@gpb.moe> wrote:

On Saturday, 14 September 2024 at 16:33, Gina P. Banyard internals@gpb.moe wrote:

> Hello internals,
>
> I came across the Directory class while doing some code exploration of ext/standard.
> This class is effectively an opaque object for Directory resources, however it doesn't behave like one, as it has existed since PHP 4.
>
> As such, I am proposing an RFC to turn this class into an opaque object.
>
> RFC: PHP: rfc:directory-opaque-object

Unless there are further comments I will be opening the vote for the RFC on Saturday.

I have changed some of the terminology and added a rationale section to the RFC:
https://wiki.php.net/rfc/directory-opaque-object

Unless there are again some comments about it, I will open the RFC on Thursday the 3rd of October.

Best regards,

Gina P. Banyard

On Tue, 2024-10-01 at 16:36 +0000, Gina P. Banyard wrote:

On Wednesday, 25 September 2024 at 10:12, Nick Lockheart
<lists@ageofdream.com> wrote:

> On Sat, 2024-09-14 at 15:33 +0000, Gina P. Banyard wrote:
> I don't suppose we could call the Directory class something else,
> like
> "SPLDirectory"?
>
> You can't make a Directory with `new` (or at least you aren't
> supposed
> to be able to), so any existing code would already get a Directory
> object with `dir()` not `new Directory()`. There would be no BC
> break
> with a rename.

This is factually incorrect.
This would be a large BC break, moreover PHP "owns" the global
namespace.

Is every single word really a reserved word in the global namespace?

Otherwise, if you are in the global namespace and try to create a
class which is called Directory this would result in an Error being
thrown.

Actually, it will not throw an error because classes are auto loaded.

The auto loader will not run because Directory is already registered.
It will instantiate a built-in Directory object.

An error would only be thrown if the file with the other Directory
class is manually included, which most people do not do anymore for
class definitions.

On Tue, Oct 1, 2024, at 22:21, Nick Lockheart wrote:

On Tue, 2024-10-01 at 16:36 +0000, Gina P. Banyard wrote:

On Wednesday, 25 September 2024 at 10:12, Nick Lockheart

<lists@ageofdream.com> wrote:

On Sat, 2024-09-14 at 15:33 +0000, Gina P. Banyard wrote:

I don’t suppose we could call the Directory class something else,

like

“SPLDirectory”?

You can’t make a Directory with new (or at least you aren’t

supposed

to be able to), so any existing code would already get a Directory

object with dir() not new Directory(). There would be no BC

break

with a rename.

This is factually incorrect.

This would be a large BC break, moreover PHP “owns” the global

namespace.

Is every single word really a reserved word in the global namespace?

Otherwise, if you are in the global namespace and try to create a

class which is called Directory this would result in an Error being

thrown.

Actually, it will not throw an error because classes are auto loaded.

The auto loader will not run because Directory is already registered.

It will instantiate a built-in Directory object.

An error would only be thrown if the file with the other Directory

class is manually included, which most people do not do anymore for

class definitions.

Hey Nick,

Is this actually an issue though? \Directory would be a weird thing to autoload. Most people tend to autoload specific namespaces. I think it would be weird to autoload into the global namespace.

Maybe I am wrong, and that is why I ask.

— Rob

Hey Nick,

Is this actually an issue though? \Directory would be a weird thing
to autoload. Most people tend to autoload specific namespaces. I
think it would be weird to autoload into the global namespace.

Maybe I am wrong, and that is why I ask.

— Rob

In a situation where people aren't using namespaces at all, it would be
normal to create your own class with a conflicting name, not knowing
there was a built-in.

On Tue, Oct 1, 2024, at 4:02 PM, Nick Lockheart wrote:

Hey Nick,

Is this actually an issue though? \Directory would be a weird thing
to autoload. Most people tend to autoload specific namespaces. I
think it would be weird to autoload into the global namespace.

Maybe I am wrong, and that is why I ask.

— Rob

In a situation where people aren't using namespaces at all, it would be
normal to create your own class with a conflicting name, not knowing
there was a built-in.

Which is why anyone creating a global namespace class, especially with a generic name like that, in 2024 is Doing PHP Wrong(tm). The top-level namespace has been considered "reserved" (at least de facto, if perhaps not sung from the rooftops) for... 15 years? Maybe not as long as there have been namespaces, but close to.

I have no strong opinions on this RFC as I've not paid close attention to it, but "we can't introduce an unnamespaced class, that's a BC break" is simply not true, and not consistent with how Internals and the stdlib are and have been developed.

--Larry Garfield

On Tue, 2024-10-01 at 18:32 -0500, Larry Garfield wrote:

On Tue, Oct 1, 2024, at 4:02 PM, Nick Lockheart wrote:
> >

Which is why anyone creating a global namespace class, especially
with a generic name like that, in 2024 is Doing PHP Wrong(tm).

OK. I'm going to go back to writing fast, efficient, and Wrong(tm) PHP,
like I have been doing for the past twenty years.

Thanks,
Nick

On Tue, Oct 1, 2024, at 23:02, Nick Lockheart wrote:

Hey Nick,

Is this actually an issue though? \Directory would be a weird thing

to autoload. Most people tend to autoload specific namespaces. I

think it would be weird to autoload into the global namespace.

Maybe I am wrong, and that is why I ask.

— Rob

In a situation where people aren’t using namespaces at all, it would be

normal to create your own class with a conflicting name, not knowing

there was a built-in.

Hey Nick,

Your reply just gave me flashbacks of the days before ctrl-click and games of “Find the Buried Implementation.” Heh.

I’m sure code like you describe exists, but I haven’t personally run into it (outside of WordPress) since 2011? In either case, auto loading was not in use. I’m not even sure how it would work (maybe a custom/manual class-map type thing)?

Sleeping on it, I do agree that Directory is a poor name for a final class. You would expect something called Directory to be abstract and be implemented in concrete objects like FileDirectory, FTPDirectory, WebDavDirectory, S3Directory, etc. For the base abstraction of a directory to be final is a bit weird, IMHO.

— Rob