Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128990 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 F14AB1A00BC for ; Tue, 28 Oct 2025 15:44:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1761666256; bh=KfJHnGeWzj53MTAzUYTLXjWzLcW1d5QXgtTDHntWH3Q=; h=References:In-Reply-To:From:Date:Subject:To:From; b=EMkm+ITTgB0lD2H9m2FxjZJoFZkZRpmliO18DQSZGuM4/MqVL0QILDe/+FPBzSMZe yTs8H7sxaEy3jJvsjeIH5nEFYXOGUXj042AspnPGVqMiHSW6iEdE7ebFANBho3QW5K 0dLGsVRPyutiQwoLaDOZZeyHyRh2l8PpIfyDwVFNCDQIeYh7LuNgDAbgw3SDiTlvZ1 omVuKMbXqMV+tzlCPuuLVJWqgChX4sq9DKY/2DNoPs9fSU0xRmz/zKQwhFqoyxixwn i9iU1mb5W0tx5e5gz2rbwxuHTeME820an8FXBeVHhu01pUNMc9gq5wjKTos2xoznkq Y1rkIuLoYR+ow== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D7B58180388 for ; Tue, 28 Oct 2025 15:44:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_40,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-qv1-f51.google.com (mail-qv1-f51.google.com [209.85.219.51]) (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 ; Tue, 28 Oct 2025 15:44:11 +0000 (UTC) Received: by mail-qv1-f51.google.com with SMTP id 6a1803df08f44-81efcad9c90so72871586d6.0 for ; Tue, 28 Oct 2025 08:44:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761666245; x=1762271045; darn=lists.php.net; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=+FxATkrhb4kFmOMDYq1twZgxLOSh9LSe3P0DSefto8Y=; b=UiguBh4SKw1bYZERUjJZNKuj01H+HQBfnZ/JkTEeI8h4nxZAU5nPaq49t5Que4DnHP j+PPl4WoL4pigNYtP6MWd2mDE2tHnWSY53i8eT3cU0mwvifHg8nsqeib5asjTR93tkA7 0XVH9w0HnQtQsDMd9Wcx5BPLy81uhZw+joZvfs1mGq6TuBna5iiDD8/8ZpTI3/uiyFX/ nnHY9QFAeYkCX0QA6FKjGKRDWYcMgOGYbLasHtGDRvT9CQqw/z120HXD1sKcj+ghGFuk RNC3xC0stB4wsTxrQXc2yMtSLhfTJ2vwz48HXB9F+8sREWrxXEgw4t7GAM/vje/G/hDf Q06w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761666245; x=1762271045; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+FxATkrhb4kFmOMDYq1twZgxLOSh9LSe3P0DSefto8Y=; b=gurAFShxpjwsnOux+gz05V6MkKAvpyEahgVH1Pu84PZqhh+a7DvClX48O39qE9PAIK 7/wEfAmCLzWQEkLjc1MkFYiSZGzJXd8XTyZofnr+mHczRcBEwAsP7iFMv8QjK4QXR4WT d3C7K26candp8S82UOlQsFtvxHOsEVD3b40IeOlHaXtEZWVXUFFjve8uTDlTPcpcEZFi U1x+Jbgw2uLXXbUnWGNyvENZh9bFgkLAFzsE76U51iAdLKtj+/Moh+TObiJ4n6h1bWYi WUnLjSV3eW6dn0D+3htrUMgi3fuGnKmAe+ctOszSbCQPjnmBTqfmvYV6pzOY4Q+OLupG j1Kw== X-Gm-Message-State: AOJu0Yxn2nS/PJo4JhPRKp8sHormRZNMvRo3ipPKr/HMRtLwnJwZD4Ma CjIsf33KJesbTPJIHlL10M4e6qPpk9jYFUTkAmpfZmwk/zww5ARup3EpA+sm+YiPRpULV1wg/hI HmMvDdANyFbh5fn04pIn2RVjgXw5eaMwCZ1TnKGM= X-Gm-Gg: ASbGnctH2KeIcBYiajhk3JVrXYO9SNUwpd4romSX0QYPtQsgZdveH/+n6FjOYhWPQFi e3cbA+M9bcYCEsAsZNTpk3N/YfLMwX+TcBKmo4bcHXWWAwMu8hjZoDrhfFCAmdmN7wLz+jfatYc HjLik8V3aZPicd3cLML4JL74dr30wqivl7AqSIxAN4oydXSzVgg938lbVBVKOXheg46CBFdP8TJ 777tp+mMKNS1b0Y5VeXq1JhDO4zZgsCjhTiKmaLEecgsLLkXyLFl98W7HhStR5MqIpZ6KM= X-Google-Smtp-Source: AGHT+IFZWQDAVCMdCASu1mndZ78OxVCcOWaM/cyGSiuc3bVPyYsrPpGvGZSBNXKIzhRENv3IbVZ0gCgsRshchABQDTg= X-Received: by 2002:a05:6214:2249:b0:87f:b2f2:c591 with SMTP id 6a1803df08f44-8800887a3b7mr465536d6.62.1761666245546; Tue, 28 Oct 2025 08:44:05 -0700 (PDT) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 28 Oct 2025 16:43:54 +0100 X-Gm-Features: AWmQ_bmhWyCe9ACXHRgkK8SeiQ9Mc34KwF66bl91k9p0j56ZuzaWkAzGCOSE4wY Message-ID: Subject: Re: [PHP-DEV] [RFC][Discussion] Add #[NoSerialize] attribute for excluding properties or classes from serialization To: PHP internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: tovilo.ilija@gmail.com (Ilija Tovilo) Hi Dmytro On Tue, Oct 28, 2025 at 12:00=E2=80=AFAM Dmytro Kulyk wrote: > > I=E2=80=99d like to open a discussion about a new proposal introducing th= e > #[NoSerialize] attribute, which allows developers to explicitly > exclude properties =E2=80=94 or even entire classes =E2=80=94 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 e= xample, arrays, collections, or parent objects) remain valid and can be saf= ely unserialized without errors, while clearly indicating that the value wa= s 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 becaus= e 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 explicitl= y 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() rem= ain 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