Re: Re: [RFC] Clone with v2

From: Date: Mon, 26 May 2025 15:10:53 +0000
Subject: Re: Re: [RFC] Clone with v2
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Hi

Clarifying on the technical questions.

Am 2025-05-26 16:37, schrieb Nicolas Grekas:
I think the RFC is missing a few bits to be complete: - making "clone" a function means suddenly a "use clone;" or a "\clone" is going to be needed to not get a perf hit, isn't it? But since $y = clone $x; is still going to be valid, how will this be handled? The RFC could give some more hints on the topic.
The implementation of making clone a function matches that of making exit() a function in PHP 8.4 (https://wiki.php.net/rfc/exit-as-function). Specifically, clone will remain a keyword and any use of a bare clone will compile to a fully-qualified call to the clone function, as if you would have written \clone(). For the same reason it will remain impossible to define a clone() function within a namespace. It will also be disallowed to use disable_functions=clone (the same as with exit and die). That clone() will become a function should be considered an implementation detail. You might start seeing a clone() frame in your stack traces, within assert(false && clone($foo)) the \clone() call will be fully-qualified in the error message output and error messages might slightly change (e.g. when passing a non-object to clone). Other than that, it should not be noticeable. Perhaps even the ZEND_CLONE opcode will remain when using clone with a single-parameter (this is similarly to the other optimization of “special functions”, such as count() or sprintf()). I have made the following changes to the RFC that should hopefully clarify things: https://wiki.php.net/rfc/clone_with_v2?do=diff&rev2%5B0%5D=1748270099&rev2%5B1%5D=1748272162&difftype=sidebyside
- writing code with a wide range of supported PHP versions means we'll start using construct such as: if (PHP_VERSION_ID>=80500) { $b = 'clone'($a, [...]); // note 'clone' is a string here, so that the line is valid syntax on PHP <= 8.4 else { // another code path for PHP 8.4 } That's of course because "use clone", "\clone" or "clone($foo)" is invalid PHP syntax currently.
Only use function clone; is currently invalid syntax (and it will remain invalid syntax, similarly to use function exit;). clone($a) currently is a perfectly valid cloning statement (with redundant parentheses) and \clone($a) is a valid call to a function called clone that does not exist: https://3v4l.org/VB3j1 But as I said above, it is not necessary to change any existing code. The RFC is clear on that: There are no backwards incompatible changes regarding the usage. When finalizing the implementation, I'll make sure to run some benchmarks to determine whether or not keeping the OPcode is worth it for the “non-with” case, or whether making clone a “frameless” function would bring any benefit. But making sure it runs fast is the job of the engine, not the job of the PHP developer and generally speaking performance characteristics can change even without RFCs.
It could make sense to tell about this and show an example like this one in the RFC.
Given that your question appears to be based on a misunderstanding, I believe adding such an example to the RFC is not useful.
- what if one gives a mangled property in the array? clone($foo, ["\0Foo\0bar" => 123]) It could be useful to write something about this case and/or at least have a test case that shows how this should behave.
As the RFC specifies, clone-with behaves exactly like regular property assignments. This means your example behaves like `$foo->{"\0Foo\0bar"} = 123;` and thus will throw “Error: Cannot access property starting with "\0"”. I have added a test to the implementation [1]. Adding that to the RFC text itself is probably not useful to the average reader, since this is not something they will encounter. Best regards Tim Düsterhus [1] https://github.com/TimWolla/php-src/pull/6/commits/6f55e142e55af013bed0f31d7dc1633ef8201bff

Thread (52 messages)

« previous php.internals (#127463) next »