Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107967 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 82321 invoked from network); 3 Jan 2020 03:47:09 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 3 Jan 2020 03:47:09 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 713A51804F3 for ; Thu, 2 Jan 2020 17:51:09 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS8075 40.64.0.0/10 X-Spam-Virus: No X-Envelope-From: Received: from NAM10-BN7-obe.outbound.protection.outlook.com (mail-bn7nam10olkn2015.outbound.protection.outlook.com [40.92.40.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 2 Jan 2020 17:51:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=SEOu1KGCMT5uYk9FNAmEor0QSRmlViw7ObWXBttqMNC5GywoNHDK8ZjQUvi3MabbxVPbMI3cOvYv2nfyiEeIN4MmeM3YUloNmW1+PCkz0y1sddrQ+t+bEGQrXTxOs7yPmzv8dYivT+DCbLF0zn5/88m2NFE2bfDjZL9SgBXbGNfyRnCALdGCIiJpPbpBM0d3EVWvEF8YUOyBVLEd2ue+snvNAmXwZhECtUM2N6zNR4WKmozYD+C+cnVNqTTxbElj4aOkg+jQuvWPP3OoCFOZ0NJaz0iKeHMzXa3z+LBHO5AffLoGp2u0BJQQcPOFradzcr9I72LG3/gPR8thBOQY5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lsHECTus2DFfrVvrqcqcs376pnrNc32rwHv7Q2hLn54=; b=bl1jUulK+PvzvNw1vokfvgpeTyuvjQdo29Oehw9eSLJqUblkW2YEM/rc97DScZsKmKEwOdP9kO19TzQJ8gLKXzIkeCSlfz8w4aCR+tj85yqKcz6tKc94rkq8OVYk9MzqiIJ0TmS5xjprMjG3xYIMzJMefLBjC1w5KUo5On+mLdIIPPQVloHWAOlZWU+llPkmHJYNuHQ4Vh7nXpC53q9zqnXbCYFKMCWWMvtfQujehkaGhqewjas0paa767p5zQoYfvWWII0BqB8GGHrpc8pqcL6iZ9sPMG9SfT61xFZ/06pwcOfcWW9c7axI6oXZg2neqBEd9SVP0WZAz20LKG56EA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=lsHECTus2DFfrVvrqcqcs376pnrNc32rwHv7Q2hLn54=; b=VQwzs67ecJeLXaUq0mGNMQutQNxDyGgyQQ0G+CfhTv/V+6uoBxGxtot0ilupdJAUm/iPHasdQwzGH6NUGPhPidcPBItxVlptjt8Q5F1lT5jScjMOnMHlWVg/3eiFxxkhjWhhsIBGX+wO/7nIZ/jqHwQt23P6fVKulX31LT93MJZibIVOuZQt9Ol7ejEown6UEDsUCi7Qn3zboQa5Kzp6vN/zm9Wys4VwBDTbzdu00Qbbol3W4/haEye+KxcymGbK9UlI5hUFW99sDb/4hXtYKxuZ/oevyEm15zUbEPwTmp9EJiAGYD2YEDT6lNkgSWh5ijgF53HDyIQ/21dEoJADKg== Received: from DM6NAM10FT060.eop-nam10.prod.protection.outlook.com (10.13.152.52) by DM6NAM10HT152.eop-nam10.prod.protection.outlook.com (10.13.153.129) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2602.11; Fri, 3 Jan 2020 01:51:07 +0000 Received: from DM5PR07MB3067.namprd07.prod.outlook.com (10.13.152.58) by DM6NAM10FT060.mail.protection.outlook.com (10.13.152.107) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2602.11 via Frontend Transport; Fri, 3 Jan 2020 01:51:07 +0000 Received: from DM5PR07MB3067.namprd07.prod.outlook.com ([fe80::29e3:53bf:163e:5beb]) by DM5PR07MB3067.namprd07.prod.outlook.com ([fe80::29e3:53bf:163e:5beb%3]) with mapi id 15.20.2602.012; Fri, 3 Jan 2020 01:51:07 +0000 To: "internals@lists.php.net" Thread-Topic: Autoloading functions/consts without a performance impact Thread-Index: AQHVwdV5EmiXz0tOK0a5kq9yFNlY0g== Date: Fri, 3 Jan 2020 01:51:07 +0000 Message-ID: Accept-Language: en-CA, en-US Content-Language: en-CA X-MS-Has-Attach: X-MS-TNEF-Correlator: x-incomingtopheadermarker: OriginalChecksum:9EEE9E66F5973561993B6EFAA7640BEE034C5C5B27C723ECCCDA1F7DF38C35FD;UpperCasedChecksum:4EAE68D41B4160F7ED5E2E465639FDE80AB628017A16FD3FD1D84D8FC4A98522;SizeAsReceived:6913;Count:42 x-tmn: [m1eB+15zw6TacaCX1MPQl/xmewx6JX6iWX1xIxZneyfvPwYxXSdlYjkIEujQDGCu] x-ms-publictraffictype: Email x-incomingheadercount: 42 x-eopattributedmessage: 0 x-ms-office365-filtering-correlation-id: 62393066-7f3e-410f-7b3b-08d78fef665c x-ms-traffictypediagnostic: DM6NAM10HT152: x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: /MyiYCZpufxlj3+zIbiVwV7Yz97bjV9CVAEQLJvAuCGzF+HNdoGyeaZ5lOkRTgSdNmDzzSYEr4Lia6wQSIjFPNIgqD/+Qv7XnK8xh1Ls4/VGQ4K7OHt/eSzMsf8fIjaSCbGOLEGc5IJO7zunBVLrsCYoOZA9zzcg2KrBsQ9YbtM49EZJm2TGJzScvhqQJ9LaNFVFVAK27vjlIb11HwfDwQDiRQoH8HhL4pSa2MgF/vo= x-ms-exchange-transport-forked: True Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: hotmail.com X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-Network-Message-Id: 62393066-7f3e-410f-7b3b-08d78fef665c X-MS-Exchange-CrossTenant-rms-persistedconsumerorg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-CrossTenant-originalarrivaltime: 03 Jan 2020 01:51:07.2227 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Internet X-MS-Exchange-CrossTenant-id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6NAM10HT152 Subject: Autoloading functions/consts without a performance impact From: tysonandre775@hotmail.com (tyson andre) After a quick search, it turns out I've mostly reinvented=0A= https://wiki.php.net/rfc/autofunc which I hadn't remembered.=0A= The `spl_autoload_*()` changes it mentions is what I had in mind=0A= =0A= There's been changes to php since then, it's been 7 years,=0A= and this adds thoughts on some implementation details.=0A= =0A= It's possible to support function / const autoloading=0A= in a way that keeps existing performance.=0A= Some of the objections at the time no longer apply.=0A= =0A= - `SOME_CONSTANT` no longer falls back to the literal string in php 8.=0A= It throws an Error.=0A= - APC (used by some implementations) is no longer supported.=0A= - Many of the objections were against the available implementations=0A= based on `function __autoload()`, not the concept of autoloading.=0A= =0A= https://www.mail-archive.com/internals@lists.php.net/msg52307.html=0A= - There wasn't much traction from leads for the concept=0A= or a Proof of Concept to vote on for that RFC (I think).=0A= =0A= What if an ambiguous `function_name()` or const outside the global=0A= namespace would attempt to autoload functions in the global namespace=0A= if it would throw an Error, but not the current namespace?=0A= =0A= `function_exists()` or `defined()` would not autoload,=0A= to preserve the behavior/performance of current programs.=0A= Anything with the callable type hint (e.g. `array_map`) would also need to = be modified,=0A= but I think it already needs to do that for method arrays and 'MyClass::met= hod'.=0A= =0A= - Same for global constants=0A= - That should avoid the performance hit - this autoloading would only be tr= iggered=0A= when php would previously throw an Error or warning=0A= for undefined functions/constants.=0A= - This would also avoid the need to load polyfill files (e.g. mbstring)=0A= or test framework files when their functions/constants are unused.=0A= - One blocker for other autoload proposals=0A= seemed to be performance if I understood correctly=0A= (e.g. attempting to autoload NS\strlen() every time strlen was called).= =0A= =0A= https://externals.io/message/54425#54616 and https://externals.io/message= /54425#54655=0A= detail this - choosing a different order of checks avoids the performance= hit.=0A= - In addition to the RFC, changing the signatures to `defined(string $name,= bool $autoload =3D false)`=0A= and `function_exists($name, bool $autoload =3D false)`=0A= might be useful ways to allow users to choose to autoload when checking f= or existence.=0A= =0A= And there'd have to be a hash map, flag, or other check=0A= to avoid recursion on the same constant/function.=0A= =0A= Background: A function call or constant usage is=0A= ambiguous if it could look for the function in two namespaces,=0A= as described by the rules documented in the below link.=0A= It's unambiguous if it ends up looking in only one namespace.=0A= =0A= https://www.php.net/manual/en/language.namespaces.rules.php=0A= The only type of ambiguous function call or global constant use is (7.):=0A= =0A= > 7. For unqualified names,=0A= > if no import rule applies and the name refers to a function or constan= t=0A= > and the code is outside the global namespace, the name is resolved at = runtime.=0A= > Assuming the code is in namespace A\B, here is how a call to function = foo() is resolved:=0A= > 1. It looks for a function from the current namespace: A\B\foo().=0A= > 2. It tries to find and call the global function foo().=0A= =0A= My approach should be in line with the current name resolution=0A= for unqualified names outside the global namespace.=0A= =0A= 1. It (first) looks for a function from the current namespace: A\B\foo().= =0A= 2. It (next) tries to find and call the global function foo().=0A= 3. (Optional) NEW ADDITION: Next, if both functions were undefined,=0A= the autoloader(s) attempt to autoload the function A\B\foo()=0A= (and call it instead of throwing if found) before proceeding to step (4.= )=0A= 4. NEW ADDITION: If both functions were undefined,=0A= the autoloader(s) attempt to autoload the global function foo()=0A= (and call it instead of throwing if found) before throwing an Error=0A= =0A= And for unambiguous calls, find and autoload the only name it has.=0A= =0A= The fact that one of the two possible functions gets cached by the php VM= =0A= in CACHED_PTR=0A= (for the lifetime of the request) the first time the function is found=0A= in either namespace will remain unchanged with this proposal.=0A= =0A= (Out of scope of the "use global functions/consts" RFC,=0A= so I'm splitting out this discussion. There is no proof of concept yet.)=0A= =0A= ------=0A= =0A= Pros:=0A= - Don't need to preload entire files and dependencies up-front whether or n= ot they're used (e.g. with composer),=0A= to supply functional libraries or frameworks, or to supply polyfills for = native modules.=0A= - Supporting this encourages using functions/global constants from namespac= es,=0A= where they were previously discouraged by lack of autoloading support,=0A= or needed manual require_once statements.=0A= - Preloading support makes it easier to avoid \NS\FooDoer::foo() instead of= \NS\do_foo() in cases which would be unnatural (e.g. classes with just one= method)=