> Instead of passing arguments to __clone(), I wondered about a new >> __clone_with(array >> $properties) that could be implemented next to __clone(), with the >> following behavior: >> >> - if only __clone is implemented, same behavior as always >> - if __clone_with is implemented, __clone is never called. Instead, the >> engine calls __clone_with with the map of properties in the "with" (or >> an empty array if no "with"). In addition and *before* the call, the >> engine >> sets the properties according to the "with" (potentially failing >> visibility/type checks as expected) >> > > Interesting approach! The rules seem clear, and as far as I'm qualified to > tell, > the implementation is viable. I'm not sure though what should happen if one > of the "clone with" assignments throws an exception? By default, > __clone_with() > would never be called in this case. Are we OK with this, right? Because > this way, > it's easy to circumvent any validation performed inside __clone_with() by > triggering > an exception (and then catching it). I don't think this is a huge problem, > since visibility > rules apply, so one cannot just blindly do silly things with someone > else's code. >
Even when catching the exception, there is no way to access the cloned instance, since it's not referenced anywhere yet, isn't it? I thought we could get it by calling $exception->getTrace(), but even this doesn't contain the cloned object as far as I tested correctly. > Also, I'm wondering whether it's worth the complexity to add support for > another magic method, > or would we be fine without this feature and its benefits? To put it > another way: how much > complexity is it worth to fix the problem of the wasteful deep cloning? > Does anyone have > an informed answer/opinion? > It's not only solving the problem of wasteful deep cloning, but also solving the problem of validating while cloning (the one Alexandru highlighted.) So yes, I think it's worth it. Also because to me shipping a solution with known shortcomings is likely going to turn into technical debt for the community and even for internals in the future. I saw your message about postponing this to 8.4. I think that's fair. Complex topic :) Nicolas