Hi

Thank you for your RFC. It is really well-written and nicely explains the various (edge) cases. I've only read through the `#[\NoSerialize]` one, since it is the topic of this RFC discussion. I agree with Ilija on all points.

Am 2025-10-29 15:35, schrieb Dmytro Kulyk:
#[NoSerialize], on the other hand, would apply to wrappers,
containers, or domain objects where serialization of the rest of the
structure should continue even if one field or nested object cannot be
meaningfully serialized.

But even for wrappers you can't guarantee that the wrapper is stored in a nullable property. When applying the attribute to a field, omitting the field makes sense, since the author of the property is the same person who is capable of adding the attribute and thus is in full control. This is different for classes where the author of the class doesn't know how and where the class is being used. I thus agree with Ilija that this should throw to clearly indicate that the user of the class is doing something incorrect and to not silently corrupt data. If an author of a class needs more fine-grained control, they can either add the attribute to individual properties themselves - or implement `__serialize()`.

> Class-level #[NoSerialize] is inherited by child classes unless explicitly 
overridden.

Can you clarify how this would work? How can you override this
attribute by omission?

    #[NoSerialize]
    class Foo {}

    /* What do I add here to remove #[NoSerialize]? */
    class Bar extends Foo {}

Class-level #[NoSerialize] is transparently inherited by child classes.
There’s currently no way to override or cancel this behavior in
descendants; the attribute remains effective throughout the
inheritance chain.

Indeed, however the “unless explicitly overridden” bit in the RFC text implies that this is possible.

As an alternative, #[NotSerializable] could be extended to
#[NotSerializable(bool $soft = false)], which would provide the same
behavior while keeping it in a separate, more consistent attribute —
avoiding the double semantics currently implied by #[NoSerialize].

I don't think that sub classes should be able to make a non-serializable parent class serializable, since they clearly won't be able to correctly restore the state of the parent class. In fact I would consider this an improvement over the existing serialization hooks where the child class can simply skip calling the parent's serializer and thus create a situation that the parent class does not expect to occur.

Initially, the idea was to make all of these cases emit warnings, but
I didn’t figure out how to implement that consistently within the
attribute validators.
At this point, I don’t see any practical reason to allow the attribute
on unsupported targets, so all such cases will be changed to
compile-time errors instead of warnings.

Yes, every clear error that is detectable at compile-time should be a hard error to make it easy for users to detect the mistake.

Best regards
Tim Düsterhus

Reply via email to