Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123343 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 qa.php.net (Postfix) with ESMTPS id 6ACA31A009C for ; Sat, 18 May 2024 10:52:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1716029606; bh=cUKEXBBB34YikT7WIDGR+3UklUhBlH1yEhfJpAqpo9w=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Tp/ikNAslW8o9KVn/MllsPj+ycQygn/8qDYryRfd7bjwmslMqqExHyPAfQnt4wTva 36YaRXa6Cv1XzW9rt5VCJdsJzpjuGsPbykhwW11ZA6ZiCLq1bkfQwG5ccnxgooWMn3 7t9hpIaAwuS/tvV1tMhcxScH6JJ7r5YwC/8XEhEWwbgp5z49UmKUieOBDOtkvp1W4U F/4/X/o6iGXem1OQ5uQM15ZalBffn8KGKdOuXpq+ue6/kIqkC6SCE0S7Vbgz4CffNk IWlqYguuHpOX5+4kMwRS3FFQ1C/D7jifQLoJJ/9Wfklsn3gd+d/V/gnJJczeEHpQAv 2AVClwZd8sDOA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 58BF018005F for ; Sat, 18 May 2024 10:53:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) (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 ; Sat, 18 May 2024 10:53:24 +0000 (UTC) Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-a59a609dd3fso739489666b.0 for ; Sat, 18 May 2024 03:52:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1716029550; x=1716634350; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=d0OvAqQwwoK/ldwddcv0HA9dRwlTz4oG3igyFXZM5B0=; b=FXVb8PLuq2Rz68YBDi+vewhWAr5PGuLGhYRW19P85Mhy91Hg9iOZiQMCmITvfpn4LI CKR2fNJXDOH+cwqELXMbeUHjhPQ+ld2usOZMF5l0TlAxeH7uIQOapJI4iO3+He+XYkho dkMkOBWFwIus4+UOS10lrIdsbJZf1fddmP+dz32vLnoz6d+YWTxBNVTCbQlT3pRJzYZI lL4El4Qxnvm2B7rSoBKcCx+KjhoNDz9DKbUC5bYB/e3aXjp54ivFLCfp8ehkpEZa0aO9 mHnsJrFkMz4pQFyp7MsWvtMU8sKIqGhSiigV9x1qb3U8Db6nHbz7DZPRgMHOwzfTX/4N +0PQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716029550; x=1716634350; h=cc: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=d0OvAqQwwoK/ldwddcv0HA9dRwlTz4oG3igyFXZM5B0=; b=b9jYd5GtTTs9HoKyNmMz+M/6Ll1FHbS8g4cd4Jwm/w7HjRFGOPlNEVbWPgAHcws1hC hNb66obld+mrIFD1uSbVaNYW4JJffEtIIz0RLXAHouov0tRBjrybc9EyRkRLVmbQbQ7t nrjPVhRwR7X2LvhLBZ7ocMM/ve4Erhh86jRLpOaLPvSR2FSncrXLSRf6zUnWSnIC39v1 Y3D5epEcmDZDRi5h8JzqJYgluzDTUm5x66aPCnhrRmyQHDQng/D5ud8gmaN15jF1LtkN 6lzHxX7AvzjFvRed2pRvjxcgDnzLVzZ2MGJfoHeseezOQ4hqyO54y66mFXAbgOepONqi V8KQ== X-Gm-Message-State: AOJu0YwDtYXZVuHcLhqgjrhG1wjLGndaUeAj6osRRSuEURFrR7T1nx8s 5bH8lmjotO8FhXdI+OGbccCIOMqCNhnu/NDkuA5KKykIoiLAdFaPtlFY/KNanRy9WZwJvEtrkgP O0WL/Kq6CMklcfKLyl8GCZc/lSNeOEA== X-Google-Smtp-Source: AGHT+IGQB1exvpU+Rutb0kiQ/J1P7BtI6UXFTE+Imk1suWAvuNDPl3Rtpnj2eMSVHjeiNJzca7kpdqLMtsqL29TY+Ic= X-Received: by 2002:a17:906:3386:b0:a59:a3ad:c3f6 with SMTP id a640c23a62f3a-a5d5903bba2mr146173066b.3.1716029549572; Sat, 18 May 2024 03:52:29 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: In-Reply-To: Date: Sat, 18 May 2024 12:52:16 +0200 Message-ID: Subject: Re: [PHP-DEV] [DISCUSSION] Checking uninitialized class properties To: Robert Landers Cc: internals@lists.php.net Content-Type: multipart/alternative; boundary="000000000000b9fd270618b843d0" From: cardamoneluigi@gmail.com (Luigi Cardamone) --000000000000b9fd270618b843d0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thank you for your feedback. I am already using a solution like the one proposed by Robert: it works but it leaves some doubts since each project can have a different name for NotSet while it seems a general concept of the language. Besides the example I proposed, I think that there are many cases where you can check if the property is initialised or not and for consistency "null" should be considered a valid initialization value. Are there any downsides in adding a specific syntax to check if a property is initialized with any value? Thank you. Luigi Cardamone Backend developer Italy Il Sab 18 Mag 2024, 11:19 Robert Landers ha scritto: > On Fri, May 17, 2024 at 11:43=E2=80=AFPM Luigi Cardamone > wrote: > > > > Hello Internals, > > during last PHPDay in Verona I discussed this topic with some of > > you and it was suggested to me to send an email here. > > > > Here is an example to describe my problem. Imagine a simple > > DTO like this: > > > > class MyDTO{ > > public ?int $propA; > > public ?int $propB; > > } > > > > Imagine that a Form processor or a generic mapper fill some of > > these fields with a null value: > > > > $dto =3D new MyDTO(); > > $dto->propA =3D null; > > > > Sometimes we use DTOs to handle PATCH requests and not all > > the properties are mapped with a value. In a scenario like this, > > "null" is often a valid value. > > > > At this point, I need a way to find if a property was initialized or > > not but unfortunately "isset" is not a solution. When I write: > > > > echo isset($dto->propA) ? 'init' : 'not-init'; > > > > I get "not-init" since isset returns true only if the variable is set > > and different from null. > > > > Full example: https://3v4l.org/4cCj0 > > > > Is the language missing a clean way to check if a property is > > initialized or not? Is there any solution to this problem? > > > > The only alternative is using reflection but I need to pass the > > property name as a string losing static analysis. > > Proposing a new language syntax like > > "is_initialized($dto->propA)" can be an interesting solution? > > > > Thank you in advance. > > > > Luigi Cardamone > > Backend developer > > Italy > > I wouldn't rely on checking initialized or not. Instead, use a sentinel > value: > > class NotSet {} > > define("NotSet", new NotSet()); > > class MyAwesomeValue { > public NotSet|null|string $aValue =3D NotSet; > } > > This way, even programmers can "unset" a property by simply setting > $value->aValue =3D NotSet without having to rely on the weird PHP > semantics of unsetting a property. You can also use this to > declaratively encode which properties cannot be unset, without having > to define it in your mapping code. > > Robert Landers > Software Engineer > Utrecht NL > --000000000000b9fd270618b843d0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thank you for your feedback.

<= div dir=3D"auto">I am already using a solution like the one
proposed by Robert: it works but it
leaves= some doubts since each project
can have a different= name for NotSet
while it seems a general concept of= the
language.

Besides the example I proposed, I think
that there are many cases where you
can check if t= he property is initialised
or not and for consistenc= y "null" should
be considered a valid init= ialization value.

Are there any downsides = in adding a
specific syntax to check if a property
is initialized with any value?

<= /div>
Thank you.

Luigi Cardamone
Backend developer
Italy

Il Sab 18 Mag 2024, 11:19 Robert Landers <= ;landers.robert@gmail.com&g= t; ha scritto:
On Fri, May 17, 2024= at 11:43=E2=80=AFPM Luigi Cardamone
<cardamoneluigi@gmail.com> wrote:
>
> Hello Internals,
> during last PHPDay in Verona I discussed this topic with some of
> you and it was suggested to me to send an email here.
>
> Here is an example to describe my problem. Imagine a simple
> DTO like this:
>
> class MyDTO{
>=C2=A0 =C2=A0 =C2=A0public ?int $propA;
>=C2=A0 =C2=A0 =C2=A0public ?int $propB;
> }
>
> Imagine that a Form processor or a generic mapper fill some of
> these fields with a null value:
>
> $dto =3D new MyDTO();
> $dto->propA =3D null;
>
> Sometimes we use DTOs to handle PATCH requests and not all
> the properties are mapped with a value. In a scenario like this,
> "null" is often a valid value.
>
> At this point, I need a way to find if a property was initialized or > not but unfortunately "isset" is not a solution. When I writ= e:
>
> echo isset($dto->propA) ? 'init' : 'not-init';
>
> I get "not-init" since isset returns true only if the variab= le is set
> and different from null.
>
> Full example: https://3v4l.org/4cCj0
>
> Is the language missing a clean way to check if a property is
> initialized or not? Is there any solution to this problem?
>
> The only alternative is using reflection but I need to pass the
> property name as a string losing static analysis.
> Proposing a new language syntax like
> "is_initialized($dto->propA)" can be an interesting solut= ion?
>
> Thank you in advance.
>
> Luigi Cardamone
> Backend developer
> Italy

I wouldn't rely on checking initialized or not. Instead, use a sentinel= value:

class NotSet {}

define("NotSet", new NotSet());

class MyAwesomeValue {
=C2=A0 =C2=A0 public NotSet|null|string $aValue =3D NotSet;
}

This way, even programmers can "unset" a property by simply setti= ng
$value->aValue =3D NotSet without having to rely on the weird PHP
semantics of unsetting a property. You can also use this to
declaratively encode which properties cannot be unset, without having
to define it in your mapping code.

Robert Landers
Software Engineer
Utrecht NL
--000000000000b9fd270618b843d0--