Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:94964 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 80638 invoked from network); 9 Aug 2016 10:33:58 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 9 Aug 2016 10:33:58 -0000 Authentication-Results: pb1.pair.com header.from=julienpauli@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=julienpauli@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.42 as permitted sender) X-PHP-List-Original-Sender: julienpauli@gmail.com X-Host-Fingerprint: 74.125.82.42 mail-wm0-f42.google.com Received: from [74.125.82.42] ([74.125.82.42:38770] helo=mail-wm0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C5/01-03404-491B9A75 for ; Tue, 09 Aug 2016 06:33:57 -0400 Received: by mail-wm0-f42.google.com with SMTP id o80so25111813wme.1 for ; Tue, 09 Aug 2016 03:33:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-transfer-encoding; bh=N/f5f2RBV5DVtXYpqW1TokQ+WmYPKQi5HYUQ2rG0TQc=; b=ufdgBIdCUzhAIOq7UH6xygV21PxsTRZamIZW3KNtU3JphiPVNe23jiydG0MUXAXNmw DHVP6Q+9oVOFd0Jo+vHIncaXBk82xTad7+y4QyMzS+IZzWVYM3jr0/smYsGrB7U6zylr pl2kBGwl6ByVhxC9tYanRudA9dgP4Fn7ajCRGhabhAfUcOLvaImRGvJ07twLzo4Vayw8 GIXljpzgzyWecTZbLiRdZMKK9uyQfFCCOSC5KCHUqc94J2uISuV+XaT8H/lUM7TIWMzr X8KpeKLGyrDFT+TRh+de5RYqXoX+r2SGBiQaS4f+UguLD3o9QAaCCY6IVgHWRNNSUma8 3FJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc:content-transfer-encoding; bh=N/f5f2RBV5DVtXYpqW1TokQ+WmYPKQi5HYUQ2rG0TQc=; b=L/j12pmt5UKSfaQJmW4Nw3PnOojJ5LkjpKO/Qi1rAejpHflYUhaefyYgkVa9Knjv1s TG6SwexyucWJXepszhJRERrXHP/HkAswV9XPz5zfSj8YEYaXbeRZPBG3v4c0sdgDLl/N nIxTpXeEdvkdY0HHaRuT4IkDh9RO0Qa7RPWu6KNeMQXiORZDgMYAeEOwGpKo0ve441cw NX8Qc33gczxh00RTjlQ43YQPmhbZNOKr35UmA6ftmDuO9+PVznBA6GGMlr2vWLO2m8D6 gj8Sw+wApU3OM4ZKV/9eSfeudjj84/q2ojztDnl+n7qrP6FcllpC5xR85z4sEgHvbDQc B4qQ== X-Gm-Message-State: AEkooutcLmWTh0kLlx7N4BQVqasey3gieqzGK/ont+MpAM/x9RCuRHLiB1UW26jFuQtRudRr+yeKzDkzMWX0ug== X-Received: by 10.28.153.70 with SMTP id b67mr21692010wme.84.1470738833930; Tue, 09 Aug 2016 03:33:53 -0700 (PDT) MIME-Version: 1.0 Sender: julienpauli@gmail.com Received: by 10.194.45.4 with HTTP; Tue, 9 Aug 2016 03:33:13 -0700 (PDT) In-Reply-To: References: Date: Tue, 9 Aug 2016 12:33:13 +0200 X-Google-Sender-Auth: HqqpdFW2c1f5mwchBBmIAhzput4 Message-ID: To: =?UTF-8?Q?Micha=C5=82_Brzuchalski?= Cc: PHP Internals List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Namespaces internal refactoring From: jpauli@php.net (Julien Pauli) On Mon, Aug 8, 2016 at 1:08 PM, Micha=C5=82 Brzuchalski 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 retriev= e > 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_namespa= ce > struct with flags and name and should not be a part of class/function nam= e. > Such change could increase performance on those Reflection* methods but n= ot > 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=3D145979255800003&r=3D1&w=3D2 > In this discussion there was also talk about private class and internal > methods http://marc.info/?l=3Dphp-internals&m=3D146005798902985&w=3D2 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-5459151fc119e0faf6f261= 62999c0cfdR2411 > > 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 brea= t > boost as it can simply comapre pointer to zend_namespace struct. > > An advantage of struct coult bring us new features like internal namespac= es > in near future simply by flags field in zend_namespace struct - in featur= e > 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 modifie= rs > 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 cou= ld > be protected and the user would get an error while implementing, extendin= g > - 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 b= e > 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: > > namespace A { > class B {} > function c() {} > } > namespace { > $cr =3D new ReflectionClass(A\B::class); > var_dump($cr->getName(), $cr->getNamespaceName()); > $fr =3D 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 cache= d! > > > Implementing such struct as zend_namespace could bring namespaces registr= y > at run-time. Such namespaces could have wheir parents as pointers to othe= r > 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 wit= h > class name and 1000 * 4 chars("Test") in quite longer namespace names tho= se > 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