On Mon, Aug 8, 2016 at 1:08 PM, Michał Brzuchalski
<mic...@brzuchalski.com> wrote:
> Hi internals,
>
> I would like to present my idea for namespaces refactoring and provide an
> RFC for them.
>
> Currently in PHP namespaces are implemented as a prefix of class or
> function name. Using ReflectionClass or ReflectionFunction we can retrieve
> class/function name and its namespace-name. In both situations it's
> implemented as substring operation on class/function name:
>
> ReflectionClass::getNamespaceName():
> https://github.com/php/php-src/blob/master/ext/reflection/php_reflection.c#L5283
> ReflectionFunction::getNamespaceName():
> https://github.com/php/php-src/blob/master/ext/reflection/php_reflection.c#L3427
>
> In both we can see the result of method is part of name.
>
> IMHO those namespaces should be implemented as a struct like zend_namespace
> struct with flags and name and should not be a part of class/function name.
> Such change could increase performance on those Reflection* methods but not
> only. I can see a good usage of such struct in implementing new features
> like class/function visibility modifiers like: private, protected,
> package-private or internal.
>
> Some time ago there was discussion about final-properties I have started
> https://marc.info/?t=145979255800003&r=1&w=2
> In this discussion there was also talk about private class and internal
> methods http://marc.info/?l=php-internals&m=146005798902985&w=2 as we can
> see in PR https://github.com/php/php-src/pull/947#discussion_r21542750
> which is little outdated there is implementation of class modifiers, and
> there is exactly the same thing I was using in my package-private
> implementation which uses string subctring comparison as we can see here in
> ZEND_API int zend_is_same_namespace(const char *fc, const char *sc)
> https://github.com/php/php-src/pull/947/files#diff-5459151fc119e0faf6f26162999c0cfdR2411
>
> IMHO those hack's are result of badly implemented namespaces and leaving
> them as they are won't bring new features highly optimized against
> execution performance, because of string comparison.
> Reimplementing namespaces as a struct could bring optimization level breat
> boost as it can simply comapre pointer to zend_namespace struct.
>
> An advantage of struct coult bring us new features like internal namespaces
> in near future simply by flags field in zend_namespace struct - in feature
> there could be some cleaning of build in classes and functions and move
> into internal system namespace eg. \PHP\DateTime or whatever - not
> important right now.
>
> Another adwantage is comparing namespaces in class/function range modifiers
> like private,protected,package-private or whatever.
>
> There could be even some kind of extension flag for namespace providing
> protection of namespace used in some extension awoiding to missusage and
> providing some extension-private class/function implementations which could
> be protected and the user would get an error while implementing, extending
> - private classes from extension or smth like that.
>
> I can see also some unconsistencies in class/function usage in PHP we can
> use A/B::class to retrieve whole-class name with namespace, there could be
> also some magic const like A/B::ns and it won't need to substring class
> name, maybe in a future ther would be need to provide such syntax for
> functions? A/c::ns where A/c is function, right now there is only way to
> pass function name into ReflectionFunction as a string, classes have
> ::class magic const and it's easy to refactor such code, eg. change
> namespace name which could lead to errors in IDE where functions are in
> namespaces! Because searching for whole function name with namespace can
> exists in code only as a string.
>
> For eg. code like that:
>
> <?php
> namespace A {
>     class B {}
>     function c() {}
> }
> namespace {
>     $cr = new ReflectionClass(A\B::class);
>     var_dump($cr->getName(), $cr->getNamespaceName());
>     $fr = new ReflectionFunction('A\c');
>     var_dump($fr->getName(), $fr->getNamespaceName());
> }
>
> Will execute string substringing for class/function getNamespaceName()
> reflection method which is simply SLOW! Such information isn't even cached!
>
>
> Implementing such struct as zend_namespace could bring namespaces registry
> at run-time. Such namespaces could have wheir parents as pointers to other
> structs like in tree so they could optimize memory usage for eg. having
> 1000 classes in Test namespace preserves right now 1000 zend_string's with
> class name and 1000 * 4 chars("Test") in quite longer namespace names those
> numbers could be significant! The same is with function names.
>
> I now it's not an easy task because there are lot of source code lines
> which use zend_class->name and same for function pointers.
>
> Nowadays probably none of extension uses namespaces so it's not a real
> problem right now to provide such change.

It is.

I agree with your thoughts.
Back in 2008, namespaces were designed and added to PHP 5.3 as just
substrings in class names.

That is not the right way to do things, but we had not that much time
to design them otherwise, and we did not want to break the API too
much by adding new structures.
So, namespaces were designed as "just" some substrings in class names,
with all the problems you spot.

I guess Dmitry will have some words about that, as he lead this
feature back in time.


Refactoring namespaces could happen, but many extensions use them, and
they are heavilly used as well in OPCache and its optimizer.

The task won't be easy, and the break will be massive for internal
(some extensions would need to be rewritten, as well as many parts of
the engine).
As such, you may target next PHP major, aka PHP 8 for your ideas.


Julien.P

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to