Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127429 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 A7DA71A00BC for ; Thu, 22 May 2025 20:29:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1747945634; bh=GHa2oO7npzt4tTtQqUuj9GNKhy6DSGTga4KEDRtZB1U=; h=Date:Subject:To:References:From:In-Reply-To:From; b=dj7t4zOIJQ3eEqmrXYg42YKBG+bRYNxt6X3WaGWq3DQMcaV3GCO2UcywNRp+5jy8L uI9fn7o2fks6cuvdgaAutkxYDOrkQXrbuX8rzVmBufdYTlbeqaMsnRAW7NXaTeevho 1hl8E0TgPj5EAZ4Jlm/m4ssKRm76c0ixXw3Y8RGxK7sBbOr7TaDQkMUHitPlySEaye 50srn7xZjzWJ6tRqq7JsYuprIc8NJCPS+EEtaajcMuayGzE7h9PALt0yzk1hovVLyi 3zmubZKuthqY+K/J7fHoTKtNBgt9FaPRFjMFX2gJQEjHzDUlZM8KE5Y/NPladDE+75 QlEL8k1qjE9XA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 9832518007C for ; Thu, 22 May 2025 20:27:12 +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=-1.4 required=5.0 tests=BAYES_05,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,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 fout-b7-smtp.messagingengine.com (fout-b7-smtp.messagingengine.com [202.12.124.150]) (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 ; Thu, 22 May 2025 20:27:12 +0000 (UTC) Received: from phl-compute-02.internal (phl-compute-02.phl.internal [10.202.2.42]) by mailfout.stl.internal (Postfix) with ESMTP id 076DA114013F for ; Thu, 22 May 2025 16:29:20 -0400 (EDT) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Thu, 22 May 2025 16:29:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rwec.co.uk; h=cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm3; t=1747945759; x=1748032159; bh=DOtN6Eutq2 DrYzL4SwzvizeVeQQzNvny1mkVbSQWx1Y=; b=vdsWKUeoLbDyg8bXxeLwXn60Tt m42+BLQTuOqt3UBcu2CBVgA1ihurGZ/8EuK68XOmACMoAF5Xo76OPaZjXDfPhJRK RUFxhV7sJmPcN3Qnij9wQ8baym7cVFdPqiN3suyi7gtZ/uA7uUaXPV3Aocxc1zO4 Qxj459fad1U6hFLmrLl3ZDHDYPji/8lIROPpGODJkDUVdaW+JiQSgRJeZl+BGDsx olY1aSsYrCIOFa0mn+rJemORjv7BXAWkkCpAHGbLrMsiht4t2jVN+jUA/G1r4+25 wuGEDVIhC+RqpCZXgumXvs2P8wspPAwnvGyMCd8cKZaqiXcYxKzpFC3w/EuA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1747945759; x=1748032159; bh=DOtN6Eutq2DrYzL4SwzvizeVeQQzNvny1mk VbSQWx1Y=; b=RkaCkfhBpTgXAWjdtCmNz8If6EB/19oXmZZ20+jdxKde+oOlhP2 OPx424PFVk6ytpqcWHwdnwnTv1rfHcD7aWVI2y2Yrjgs2k+/cL6jnCBXNqIBoimw C+JLR43Tyl1WS2xaSLHHBOg9VpmxzGtKc3gvWM4btEBdhWrfCQ+Qw4CndynZC/3U tmDHLK9TFw/4UOH32LRq+hzzPppIGvl6pV5wC6ubi/SlD9jgcMVTt63clVTLnc89 3vAMQNRj4mNP89gXdvcazHbZDjDhYseFu9JUAXMrQLs2PfG+u6jzN9NG6/B3B9ZL fzjFDsjSt6zhRkJ631l0QR05LdYTUi4JRoQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgdeiledvucdltddurdegfedvrddttd dmucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgf nhhsuhgsshgtrhhisggvpdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttd enucenucfjughrpegtkfffgggfuffvfhfhjgesrgdtreertddvjeenucfhrhhomhepfdft ohifrghnucfvohhmmhhinhhsucglkffoufhorfgnfdcuoehimhhsohhprdhphhhpsehrfi gvtgdrtghordhukheqnecuggftrfgrthhtvghrnhepheetleeiiefgueduieeuieffvdev heduueefkeejuefgffeftdeitdegtedtleetnecuvehluhhsthgvrhfuihiivgeptdenuc frrghrrghmpehmrghilhhfrhhomhepihhmshhophdrphhhphesrhifvggtrdgtohdruhhk pdhnsggprhgtphhtthhopedupdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehinh htvghrnhgrlhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: id5114917:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Thu, 22 May 2025 16:29:18 -0400 (EDT) Content-Type: multipart/alternative; boundary="------------BjAe0ZgzJQiMmSddGCoEd7aH" Message-ID: <354cb888-97c4-4f8c-a0da-359d1e63c0f9@rwec.co.uk> Date: Thu, 22 May 2025 21:29:18 +0100 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PHP-DEV] Module or Class Visibility, Season 2 To: internals@lists.php.net References: <3ae9a6ea-f135-472b-b2bf-e6cd6ebad299@app.fastmail.com> <9A26F72B-D0EF-414F-B193-BED3CAB26A0B@rwec.co.uk> <9f6a0d6e-27c3-4f77-aed6-e55147442b6f@app.fastmail.com> <673fd2db-b07f-439b-a4f2-e9519108d159@app.fastmail.com> <78641D8B-AF1D-4912-920A-D75A37C32F05@rwec.co.uk> Content-Language: en-GB In-Reply-To: From: imsop.php@rwec.co.uk ("Rowan Tommins [IMSoP]") This is a multi-part message in MIME format. --------------BjAe0ZgzJQiMmSddGCoEd7aH Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 22/05/2025 12:09, Michael Morris wrote: > > > I've tried several times to explain why I think Linux containers > are a good analogy; I'm not sure if you didn't understand, or just > didn't agree, so I don't know what else I can say. > > > I have no disagreement with that, but it's an implementation detail. > I'm not there yet - I'm just trying to describe what I think is needed > from outside the engine. I think this is where we're not seeing eye to eye, and why we're getting frustrated with each other, because I see it as far more fundamental than details you have already gone into, like how autoloading will work. Perhaps a more realistic example will help, and also avoid the confusion over "A, B, and D" from earler. Imagine a WordPress plugin, AlicesCalendar, which uses the Composer packages monolog/monolog and google/apiclient. The google/apiclient package also requires monolog/monolog. Another WordPress plugin, BobsDocs, also uses both monolog/monolog and google/apiclient, but using different versions. Inside those different places, there are lines of code like this: $logger = new \Monolog\Logger('alices-calendar'); // in AlicesCalendar $logger = new \Monolog\Logger('bobs-docs'); // in BobsDocs $logger = new \Monolog\Logger('google-api-php-client'); // in google/apiclient We need to rewrite those lines so that they all refer to the correct version of Monolog\Logger. If every package/module/whatever rewrites the classes inside every other package/module/whatever, we might start with this: $logger = new \AlicesCalendar\Monolog\Logger('alices-calendar'); // in AlicesCalendar $logger = new \BobsDocs\Monolog\Logger('bobs-docs'); // in BobsDocs $logger = new \GoogleApiClient\Monolog\Logger('google-api-php-client'); // in google/apiclient That only works if we somehow know that AlicesCalendar and BobsDocs use the same google/apiclient; if not, we need four copies: $logger = new \AlicesCalendar\Monolog\Logger('alices-calendar'); // in AlicesCalendar $logger = new \AlicesCalendar\GoogleApiClient\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from AlicesCalendar $logger = new \BobsDocs\Monolog\Logger('bobs-docs'); // in BobsDocs $logger = new \BobsDocs\GoogleApiClient\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from BobsDocs All of these are separate classes, which can't be used interchangeably, and the names get longer and longer to isolate dependencies inside dependencies. But we don't actually need the Monolog\Logger used by AlicesCalendar to be a different version from the one used by google/api-client. In fact, it would be useful if they were the same, so we could pass around the objects interchangeably *inside* the plugin code. So what we want is some way of saying that AlicesCalendar and BobsDocs are special; they want to isolate code in a way that normal modules/packages/whatever don't. Then we can have 2 copies of Monolog\Logger, not 3 or 4: $logger = new \AlicesCalendar\Monolog\Logger('alices-calendar'); // in AlicesCalendar $logger = new \AlicesCalendar\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from AlicesCalendar $logger = new \BobsDocs\Monolog\Logger('bobs-docs'); // in BobsDocs $logger = new \BobsDocs\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from BobsDocs In this case, PHP doesn't need to know monolog/monolog even exists. It just puts either "AlicesCalendar" or "BobsDocs" on any class name it sees. Before we can even think about *how* we'd implement the rewriting (or shadowing, or whatever) we need some requirements of *what* we want to rewrite. By suggesting an image of "containers" or "sandboxes" rather than "packages" or "modules", I was trying to define the requirement that "AlicesCalendar and BobsDocs are special, in a way that monolog/monolog and google/apiclient are not". -- Rowan Tommins [IMSoP] --------------BjAe0ZgzJQiMmSddGCoEd7aH Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit
On 22/05/2025 12:09, Michael Morris wrote:

I've tried several times to explain why I think Linux containers are a good analogy; I'm not sure if you didn't understand, or just didn't agree, so I don't know what else I can say.

I have no disagreement with that, but it's an implementation detail. I'm not there yet - I'm just trying to describe what I think is needed from outside the engine.


I think this is where we're not seeing eye to eye, and why we're getting frustrated with each other, because I see it as far more fundamental than details you have already gone into, like how autoloading will work.

Perhaps a more realistic example will help, and also avoid the confusion over "A, B, and D" from earler.

Imagine a WordPress plugin, AlicesCalendar, which uses the Composer packages monolog/monolog and google/apiclient. The google/apiclient package also requires monolog/monolog.

Another WordPress plugin, BobsDocs, also uses both monolog/monolog and google/apiclient, but using different versions.


Inside those different places, there are lines of code like this:

$logger = new \Monolog\Logger('alices-calendar'); // in AlicesCalendar
$logger = new \Monolog\Logger('bobs-docs'); // in BobsDocs
$logger = new \Monolog\Logger('google-api-php-client'); // in google/apiclient

We need to rewrite those lines so that they all refer to the correct version of Monolog\Logger.


If every package/module/whatever rewrites the classes inside every other package/module/whatever, we might start with this:

$logger = new \AlicesCalendar\Monolog\Logger('alices-calendar'); // in AlicesCalendar
$logger = new \BobsDocs\Monolog\Logger('bobs-docs'); // in BobsDocs
$logger = new \GoogleApiClient\Monolog\Logger('google-api-php-client'); // in google/apiclient


That only works if we somehow know that AlicesCalendar and BobsDocs use the same google/apiclient; if not, we need four copies:

$logger = new \AlicesCalendar\Monolog\Logger('alices-calendar'); // in AlicesCalendar
$logger = new \AlicesCalendar\GoogleApiClient\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from AlicesCalendar

$logger = new \BobsDocs\Monolog\Logger('bobs-docs'); // in BobsDocs
$logger = new \BobsDocs\GoogleApiClient\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from BobsDocs

All of these are separate classes, which can't be used interchangeably, and the names get longer and longer to isolate dependencies inside dependencies.


But we don't actually need the Monolog\Logger used by AlicesCalendar to be a different version from the one used by google/api-client. In fact, it would be useful if they were the same, so we could pass around the objects interchangeably *inside* the plugin code.

So what we want is some way of saying that AlicesCalendar and BobsDocs are special; they want to isolate code in a way that normal modules/packages/whatever don't. Then we can have 2 copies of Monolog\Logger, not 3 or 4:

$logger = new \AlicesCalendar\Monolog\Logger('alices-calendar'); // in AlicesCalendar
$logger = new \AlicesCalendar\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from AlicesCalendar

$logger = new \BobsDocs\Monolog\Logger('bobs-docs'); // in BobsDocs
$logger = new \BobsDocs\Monolog\Logger('google-api-php-client'); // in google/apiclient when called from BobsDocs

In this case, PHP doesn't need to know monolog/monolog even exists. It just puts either "AlicesCalendar" or "BobsDocs" on any class name it sees.


Before we can even think about *how* we'd implement the rewriting (or shadowing, or whatever) we need some requirements of *what* we want to rewrite. By suggesting an image of "containers" or "sandboxes" rather than "packages" or "modules", I was trying to define the requirement that "AlicesCalendar and BobsDocs are special, in a way that monolog/monolog and google/apiclient are not".


--
Rowan Tommins
[IMSoP]


--------------BjAe0ZgzJQiMmSddGCoEd7aH--