What is the general feeling about reserving a namespace for PHP's built
in classes?
As the number of built-in classes grows over time, the chances of
naming collisions with user classes will grow.
When naming conflicts occur, they happen in an unexpected way, that
does not make it readily obvious that a name conflict has occurred.
That's because most projects use auto loaders, and the auto loader only
runs if a class is unregistered.
If a user creates a class called "Directory" and places it in the auto
load path, then tries to instantiate it, they will not receive any
error.
If the user then tries to call Directory::MyMethod(), they are told
that the method doesn't exist, even when they are staring at the class
definition. The user presumes that the auto loader has found and loaded
the class, because there isn't a "class not found" message.
If new built-in classes are added in the future using common dictionary
words as the name, there is a good chance of confusing breaks when the
PHP version is updated.
Now that namespaces are a thing in PHP, maybe we should take a page
from C++'s book and have users include the standard library classes
they want, when they need them.
ie:
use \spl\Directory;
I'm also wondering if there would be any performance benefit to not
having a bunch of internal classes pre-registered "just in case".
Hi
What is the general feeling about reserving a namespace for PHP's built
in classes?
see https://wiki.php.net/rfc/namespaces_in_bundled_extensions
Best regards
Tim Düsterhus
Hi
What is the general feeling about reserving a namespace for PHP's
built
in classes?see https://wiki.php.net/rfc/namespaces_in_bundled_extensions
Best regards
Tim Düsterhus
Thank you. I've read through the RFC and see it was approved. Is it too
late to comment on this? My concern is that placing things into new and
arbitrary namespaces as per the RFC is just a different variation on
the global name problem.
The problem, as I see it, is that new names that come bundled with PHP
can be arbitrary. If new bundled classes can have arbitrary dictionary
words as the namespace, then we may actually have a bigger problem as
no name space is safe from future collisions.
The biggest problem with built-ins is that you can't unregister them.
I think a better solution would be to have one namespace for all
bundled classes, so that a specific namespace is reserved in advance.
From the RFC:
3rd-party extensions clearly cannot start out under a PHP namespace,
as they have no direct relation to, endorsement by, or oversight of
the PHP project. If all symbols in bundled extensions are to be
prefixed by PHP, this would require a rename of all symbols when an
extension moves from 3rd-party to bundled.
I think this is the real issue: How could we use a small number of
reserved namespaces for built-ins, but deal with permanence of those
names as things move around?
What if we had a grandfather policy?
Once a third party is accepted into core, it gets a core namespace.
If it is later removed from core, it gets grandfathered into being
allowed to use the core namespace, even if it is once again third
party.
The RFC did mention that once something moves to core, it seldom moves
back out, if ever.
There was a vote on something similar four years ago, 13(no)/17(yes),
declined. It was four votes shy of passing:
https://wiki.php.net/rfc/php_namespace_policy
There was more in that proposal though: the use of component namespaces
in addition to just \php
.
Could this issue possibly be revisited and voted on with a more narrow
scope?
I think if we reserved \php
and \ext
, then there would be no need
to have multi-level namespaces, like the prior RFC proposed. I think
every standard class could just be \spl\classname
without any naming
conflicts between core classes. And that would also avoid future
namespace collisions.
Hi
Thank you. I've read through the RFC and see it was approved. Is it too
late to comment on this? My concern is that placing things into new and
arbitrary namespaces as per the RFC is just a different variation on
the global name problem.
Commenting is of course possible, but any changes would require another RFC.
In any case, the RFC's policy has already been used in the design of the
new randomness API added in PHP 8.2.
I think a better solution would be to have one namespace for all
bundled classes, so that a specific namespace is reserved in advance.
Needing to prefix everything by \PHP or something like this would
provide for a terrible developer experience when using the standard library.
There was a vote on something similar four years ago, 13(no)/17(yes),
declined. It was four votes shy of passing:
This is false. That RFC required a 2/3 majority to pass.
I think if we reserved
\php
and\ext
, then there would be no need
to have multi-level namespaces, like the prior RFC proposed. I think
every standard class could just be\spl\classname
without any naming
conflicts between core classes. And that would also avoid future
namespace collisions.
Not using sub-namespaces would require making the classnames overly
specific, because there's some names that make sense in different
domains. An example would be a Client
or Connection
.
Best regards
Tim Düsterhus
I think a better solution would be to have one namespace for all
bundled classes, so that a specific namespace is reserved in
advance.Needing to prefix everything by \PHP or something like this would
provide for a terrible developer experience when using the standard
library.
We're already there.
If I want to have a Directory class, I need to put it in a namespace.
But then, if I'm using namespaces, I need to put a \
in front of
every built-in class and function or else take a performance hit.
So we're already where we need to do \isset, \array_key_exists, etc to
get the built-in functions without doing a local namespace
lookup first.
I think there are several things to consider here:
- Could we have a global setting (maybe php.ini) that makes all built-
in functions (not built in classes) directly accessible in any
namespace? That is:
// php.ini
AlwaysUseGlobalFunctions = yes
Then:
// myclass.php
namespace foo;
class Bar{
function MyMethod($a,$b){
if(array_key_exists($a,$b)){ // no \ before array_key_exists
// do something
}
}
}
And with that option set, PHP will know that array_key_exists is
\array_key_exists, even without the slash, and without checking the foo
namespace for an array_key_exists function first?
My understanding is that some built-in functions have their own opcode,
that doesn't get triggered when those built-in functions are called in
a namespace, unless the built-in is called with a \
.
Having all functions default to global would make namespaces a lot
more user friendly to work with, since we wouldn't have to put
backslashes in front of everything.
- I think built-in classes are nice, but having classes pre-registered
in the global namespace can cause a lot of frustration.
ie. "GlobIterator::__construct() expects at most 2 arguments, 3 given".
Except, my GlobIterator takes exactly three arguments, so why does....
Oh. I see, there's already a GlobIterator registered.
I think the sane approach is to have the (user land) developers pull
built-in classes into the global namespace when needed with use
.
If I want the built-in GlobIterator, I should specify that with:
use \spl\GlobIterator;
Then I know there's a GlobIterator class because I just called for it.
Le 25 juil. 2024 à 05:22, Nick Lockheart lists@ageofdream.com a écrit :
- Could we have a global setting (maybe php.ini) that makes all built-
in functions (not built in classes) directly accessible in any
namespace? That is:// php.ini
AlwaysUseGlobalFunctions = yesThen:
// myclass.php
namespace foo;
class Bar{function MyMethod($a,$b){
if(array_key_exists($a,$b)){ // no \ before array_key_exists
// do something
}
}
}And with that option set, PHP will know that array_key_exists is
\array_key_exists, even without the slash, and without checking the foo
namespace for an array_key_exists function first?My understanding is that some built-in functions have their own opcode,
that doesn't get triggered when those built-in functions are called in
a namespace, unless the built-in is called with a\
.Having all functions default to global would make namespaces a lot
more user friendly to work with, since we wouldn't have to put
backslashes in front of everything.
Hi,
For the case of functions (and constants) in the global namespace, there was an RFC on the subject about 4 years ago, which has been declined; see: https://wiki.php.net/rfc/use_global_elements and the discussion threads referenced at the bottom of that page.
—Claude
For the case of functions (and constants) in the global namespace,
there was an RFC on the subject about 4 years ago, which has been
declined; see: https://wiki.php.net/rfc/use_global_elements and the
discussion threads referenced at the bottom of that page.
The top of the RFC correctly outlines the problem; a problem that still
exists. Maybe the proposed solution wasn't the best approach, but it
still remains an issue: Classes that are built-in to PHP are and will
cause naming collisions with developer code.
I think the C++ approach is simple and elegant:
using std::string;
The C++ standard library will never collide with user code as you ask
for it when you want it.
For the case of functions (and constants) in the global namespace,
there was an RFC on the subject about 4 years ago, which has been
declined; see: https://wiki.php.net/rfc/use_global_elements and the
discussion threads referenced at the bottom of that page.
What about:
namespace foo;
use global functions;
class MyClass{
// do stuff
}
The use global functions
directive goes after the namespace
declaration, but before any other code. It applies to the entire file,
but only to the current file.
It tells the parser that, if a function call is found in the file, use
the global function. Do not make an NS lookup op code, and if the
function is a recognized built-in with a dedicated op code, use the
dedicated op code.
Methods and classes are unaffected.
I think a better solution would be to have one namespace for all
bundled classes, so that a specific namespace is reserved in
advance.Needing to prefix everything by \PHP or something like this would
provide for a terrible developer experience when using the standard
library.
What are people's thoughts on requiring a use statement to make built-
in classes available in the global namespace?
What are people's thoughts on requiring a use statement to make built-
in classes available in the global namespace?
No.