Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127341 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id F24991A00BC for ; Tue, 13 May 2025 15:31:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1747150165; bh=sMFEvRL8kIPVLrF9dJ+G+vhfpI8Pw5/4ToJrwj3Dems=; h=From:Date:Subject:To:From; b=FyF4bDGY93rO4rHN98Kx/Dk6DfpA6pjwrL4o6AvYFXXoUqFoO0pO/oqlP+afTDuQf DnIp2MmWi0ZObcMYZWNinUysFU+olb4cM9k7NnSXx1FaWt6wBIDoy9zKPrNitDRl83 6gUGERbPjC1UHIzU0wWXN7vtDXNzKoMbavb0x2oVVVbxaG5n+BFZqpV8um3Dar9jYM cRIWGwiT1pzjbIwWL++JpsA/Kc9uEdN+8VFyTLe2ahUfpACePe0/sTqQ/47uVGAkfP jPX3Du9S5u+Zciyq7onMw0kiVSE05tCYezsZV+y/uhsvBGN2nbqZIqprjJ0JwY8lZD daj1N2aJYWzQA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 37B7C1801D5 for ; Tue, 13 May 2025 15:29:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-yw1-f178.google.com (mail-yw1-f178.google.com [209.85.128.178]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 13 May 2025 15:29:24 +0000 (UTC) Received: by mail-yw1-f178.google.com with SMTP id 00721157ae682-70a569c592bso1277227b3.1 for ; Tue, 13 May 2025 08:31:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747150295; x=1747755095; darn=lists.php.net; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=OCUPoqkF+QtcJfkffCEGedQwaDIHHztYXrlE788X8HE=; b=c5LyGCOh5Y4S/ZPGlrA/1kB/ZAS0qfKoLh4nGlURchxqEElnLPGrEQGf9mZm+qdXOa psgxq0v4hC4Pn/uvKhIbpHpwB/xAULkgJ/KFoeoQOX0siBiKOAswXXOfuBdJG/KJz7DB uvojNoExRuD1DI66fjFbh+UzKNB6Xj7WsWB15pgCUitN98uwMaLZgFQXiChwq8DHTrSx v/DiWiHj6nfjHd2vF53LdgSff3J9n6p6z8n6nmTLwARf8foV8glCKnEyhqFk1nlGEmVD VqbCf4yzAnxoSjWtnNEs4lRkA98oQ97JHUFXb43s2sowGiOwyVuD+wRNsNWE6CkCKESd axKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747150295; x=1747755095; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=OCUPoqkF+QtcJfkffCEGedQwaDIHHztYXrlE788X8HE=; b=XYFCG4t859k2gjZw71WkwvUg9mRn8e9EcSnnh7NyEdlbEq0nf1XLEZFZS4BbZ+mKCq QcyvvdJMG+lxVmqKJziYksEIVp3c6OwOqVKU4agCcAjmi2YmEPlOGG2lkn2/Ex2womkw lxLPEP0EHcWMCDW+kevxK0u+EvplYlHnIVlqKyY4GYLUtxmgYHB+SrCBGEaZm1eYutTZ 1Qd1ZFGtlM6gGV1nZlCiCaiikCforVIkTUROEEt09/g6AkaKms3CpqTvWwg/d9EA5Du2 EzEVnPHr1ywGNkV4Fqbo2qc3b5P3tShvLSposa/N+aWdP949e/dslrXw1BEbq2U5A/ZY cFZQ== X-Gm-Message-State: AOJu0Ywjoz4WEYqyF6hrW1HadfAONf8PuIHVN3Hwydf6ifhDf2QTj//k antgNK+c/DQuUJZdaH6TI3JlsNheMgiXayXvHUAqWVg2YQR1HFjidRSjylYYRsUahbbR8kvuW9I E7IwWIhEF1dL1/PXKr7LQDMam7V2/tYTsNDo= X-Gm-Gg: ASbGncuvdA+CSwWnJSiGsoIVYHYPgrcenbazOfXDfuC+s+lAwWydItGGk9p892hFN6y JH9icqJSZCCbMoNBWZb/m2ieEcf0PNjWijdSxgUjoohfMyYHXbsjfD1o8t4pHwkMF12442n9GBO 3nS/57EQ5szqTbI858tCt6LtmN8cUhqFMcOi13rdkvokofldZE3XGkBYDfIyVt28Q= X-Google-Smtp-Source: AGHT+IEkPdRsa89EI7ZnbEFTkxZKnlwWXTNWRXfZd/xgRQM9wwqkOFznBtMBIG6Xn0dAsLgaJ1F3FpOyW/z0mASdTb4= X-Received: by 2002:a05:690c:8:b0:70a:be85:5389 with SMTP id 00721157ae682-70abe855ff2mr71593787b3.8.1747150294444; Tue, 13 May 2025 08:31:34 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Tue, 13 May 2025 12:30:58 -0300 X-Gm-Features: AX0GCFu8UCHhZv0vnJf0dJrdRXA6AdfBG2auDtS8fhnk9a_sbzxNubTZEvg7XXA Message-ID: Subject: [PHP-DEV] Module or Class Visibility, Season 2 To: PHP internals Content-Type: multipart/alternative; boundary="000000000000ab746406350620e9" From: deleugyn@gmail.com (Deleu) --000000000000ab746406350620e9 Content-Type: text/plain; charset="UTF-8" Hi! It's been a few days since I wanted to send this email to internals, but real life has been a bit chaotic so I apologize if it comes off as if I didn't research the archives enough. I glossed over the Module conversation from 10 months ago and the one that recently surfaced and after deeply thinking about Rowan's and Larry's comments I wanted to throw this idea into the pit. Lets preface the conversation with the fact that 1) a module system for PHP has been discussed for several years and 2) if there was an easy and perfect solution it would have been long implemented by now. With that in mind, I think there are mainly two major "camps": the ones that would support something new similar to Node ESM vs CommonJS and those who won't. Having dealt with this mess on the NodeJS side, I'm still on the side that would support it because even though it's been 10 years worth of "mess", it has greatly empowered progress. But I think PHP is too conservative to indulge this camp, so I'm going to focus on Rowan's and Larry's position of "we need something that builds on top of namespace, not replace it". If we consider how GitHub, Composer and Docker Hub works, we can pin a very important aspect of "namespaces": {entity}/{project}. Entity may either be an individual or an organization, but the concept is mostly the same. Although it can be argued that PHP has nothing to do with that, I think that could be a "good-enough" foundation considering the complexity of the subject. Here is what we could do: ```php
Hi!

It's been a few days= since I wanted to send this email to internals, but real life has been a b= it chaotic so I apologize if it comes off as if I didn't research the a= rchives enough. I glossed over the Module conversation from 10 months ago a= nd the one that recently surfaced and after deeply thinking about Rowan'= ;s and Larry's comments I wanted to throw this idea into the pit.
=

Lets preface the conversation with the fact that 1) a m= odule system for PHP has been discussed for several years and 2) if there w= as an easy and perfect solution it would have been long implemented by now.= With that in mind, I think there are mainly two major "camps": t= he ones that would support something new similar to Node ESM vs CommonJS an= d those who won't. Having dealt with this mess on the NodeJS side, I= 9;m still on the side that would support it because even though it's be= en 10 years worth of "mess", it has greatly empowered progress. B= ut I think PHP is too conservative to indulge this camp, so I'm going t= o focus on Rowan's and Larry's position of "we need something = that builds on top of namespace, not replace it".

=
If we consider how GitHub, Composer and Docker Hub works, we can pin a= very important aspect of "namespaces": {entity}/{project}. Entit= y may either be an individual or an organization, but the concept is mostly= the same. Although it can be argued that PHP has nothing to do with that, = I think that could be a "good-enough" foundation considering the = complexity of the subject. Here is what we could do:

```php
<?php declare(strict_types=3D1);
=
namespace Acme\ProjectOne
<= /span>{
public class Foo
{} // same as class Foo {}

private class Bar {} <= span style=3D"color:rgb(140,140,140);font-style:italic">// only visible ins= ide Acme\ProjectOne

protected class = Baz {} // visible inside Acme
}

namespace Acme\ProjectTwo
{<= br> new \Acme\ProjectOne\= Foo; // Wor= k as always

= new \Acme\ProjectOne\Bar; // Fa= tal error: Uncaught Error: Cannot instantiate private class \Acme\ProjectOn= e\Bar from \Acme\ProjectTwo

new \Acme\ProjectOne\Baz; // Works
}

= namespace Corp\Corp
{
new \Acme\ProjectOne\<= /span>Foo; // Work as always

new \Acme\ProjectOne\= Bar; // Fatal error: Uncaught Error: Cannot in= stantiate private class \Acme\ProjectOne\Bar from \Corp\Corp

new \Acme\P= rojectOne\Baz; // Fatal error: Uncaught Erro= r: Cannot instantiate protected class \Acme\ProjectOne\Baz from \Corp\Corp<= br>}


function = (\Acme\ProjectOne\Foo $foo) {} // Works = as always

function (\Acme\ProjectOne\Bar $bar) {} <= span style=3D"color:rgb(140,140,140);font-style:italic">// Open question: a= llow or disallow it?

function (\Acme\ProjectOne\Baz $baz) {} // Open = question: allow or disallow it?
``= `

This would allow public, private and protected classes in a= way that I believe to be useful for the large ecosystem that surrounds Com= poser. From my extremely limited understanding of the engine, I think the e= asy/natural step would be to allow private/protected classes to be recei= ved=C2=A0outside its namespace because a type declaration does not trig= ger autoload. However, an important question is whether this is enough grou= ndwork that could lead to optimizations that have been discussed when the t= opic of module is brought up. For instance, if type-hint outside the module= is disallowed, could that make it easier to pack and optimize an entire mo= dule if we could instruct PHP how to load all symbols of a namespace all at= once? I don't know.
------------------------

As I'= ;m writing this down I don't know if it could be related or if its some= thing only making sense inside my head, but I see the above proposal paired= with a potential amendment to PSR-4 (and Composer), to stimulate the commu= nity to pack small related symbols in a single file with an opt-in approach= :

composer.json:
```
// ...
&quo=
t;autoload": {
&qu= ot;psr-4-with-module": {
"App\\": &q= uot;app/",
}<= br>},
// ...
```

```
<?php declare(strict_types=3D1);

// app/Foo/Bar.php
namespace
App\Foo;
class Ba= r {}


// app/Foo.module.php
na= mespace App\Foo;
enum Baz {}
enum Qux {}<= br>

new \App\Foo\Bar<= /span>; // loads a= pp/Foo/Bar.php
\App\Foo\Baz::option; // file app/Foo/Baz.php does not ex= ist, tries app/Foo.module.php before giving up
\App\Foo\Qux::= option; // = app/Foo.module.php has been loaded and Qux has been registered already
```

Thoughts?

--
Ma= rco Deleu
--000000000000ab746406350620e9--