Hi Dmytro On Tue, Oct 28, 2025 at 12:00 AM Dmytro Kulyk <[email protected]> wrote: > > I’d like to open a discussion about a new proposal introducing the > #[NoSerialize] attribute, which allows developers to explicitly > exclude properties — or even entire classes — from native PHP > serialization. > > RFC: https://wiki.php.net/rfc/no_serialize_attribute > Implementation: https://github.com/php/php-src/pull/20074
Thank you for your proposal. I have a few comments. > When applied to a class, instances will be serialized as NULL. I don't understand the rationale for diverging from the existing @not-serializable behavior of internal classes, which throw when attempted to be serialized (e.g. Random\Engine\Secure). I see there's also a separate RFC to introduce that behavior: https://wiki.php.net/rfc/not_serializable_attribute I don't think there's a need for both of these attributes. To demonstrate, how would we even decide whether an internal class like PDO should get the #[NoSerialize] or #[NotSerializable] attribute? Informing the user of potentially incorrect serialization is the prudent option, and if they would like to skip the serialization of a property containing a PDO object they can simply mark it as #[NoSerialize]. The RFC says: > This approach ensures that data structures containing such objects (for > example, arrays, collections, or parent objects) remain valid and can be > safely unserialized without errors, while clearly indicating that the value > was intentionally omitted. But is replacing unserializable objects with NULL in nested arrays really the safe choice? In these cases, I feel like a custom serializer that consciously replaces the object is warranted. This might also cause problems for typed properties: #[NoSerialize] class PDO {} class Foo { /* Will be happily serialized as NULL, but can't be restored because the * property is not nullable. */ public PDO $connection; } To summarize, I'd prefer if #[NoSerialize] on classes would cause serialize() to throw, like we already do for @not-serializable. > 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 {} > Out of scope: JSON (json_encode(), JsonSerializable) and var_export() remain > unaffected. Any future attempt to exclude properties marked as #[NoSerialize] from json_encode() would be backwards incompatible after this RFC has been implemented. To avoid this BC break, json_encode() would need a separate attribute (e.g. #[NoJsonEncode]). That sounds reasonable, but should be spelled out in the RFC. > Invalid Targets & Compile-Time Diagnostics What's the rationale for warning for some, but erroring for others? Ilija
