Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:122974 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 9E5951A009C for ; Fri, 5 Apr 2024 16:40:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1712335276; bh=6Qqdcfacs7swfBgRavA7tUb3P01ID2oZ+yv+gjWoNc4=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Vwq8f79ogFPo2/TdkJQBGM8DuK6BvssVJcVvGDriobxK5jwa2JOFOTjSjd7ssmrqc U4mijQ680vHV1pDcluB2UJUwiKQHxOm8lCpioHbtikTCiWVl5tU2m/wWM9J0cGp88q z6wYCzbTqaFUP+XQjmfmo4+WipFA8jye76nW6DNEHsHUy33iHUX1AVMg+2nV21b+E/ rPyOkXaYWz7bLVeuVtzDuluw/QboSp4FeS7v5uDuf2KJc1ucPDYoe79xs6+coUSzTL qYNz40vnE3pojCT5U1lsClE4Ss1Xa+yHqDYI62KNczjsLE2vNRB3LlW944cmu4pEoE 6jWJF4TuVqSig== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 04C131805A5 for ; Fri, 5 Apr 2024 16:41:15 +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,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: No X-Envelope-From: Received: from mail-lf1-f42.google.com (mail-lf1-f42.google.com [209.85.167.42]) (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 ; Fri, 5 Apr 2024 16:41:14 +0000 (UTC) Received: by mail-lf1-f42.google.com with SMTP id 2adb3069b0e04-516c5c39437so3244710e87.1 for ; Fri, 05 Apr 2024 09:40:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jolicode.com; s=google; t=1712335243; x=1712940043; 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=AA+m2zZT0NrjJmNIRQyF5mkALkOx5XPB+WjbvRV2MKw=; b=bv0G2g6bTj64tEAd19b6GIQpGM2i/6KzwNxGHrozQCbTKS9ZliUigFtt4uYrMibxGo PTdawj52cjWjneEF4PZ/ofudkD+x/idOQh5NLTm0e3upPtlQVM/HhqgkxdoltxaZk+dy 8kWoY2ywfJI7SckB+Oub0VMFUcQln/Qf/kCEs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712335243; x=1712940043; 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=AA+m2zZT0NrjJmNIRQyF5mkALkOx5XPB+WjbvRV2MKw=; b=iKl+SdIvikawbmu7qp+tKhKqYTLmf1MNTUGR7kWZNu4Z42Vy3w5G1Emki3bzyyFQc6 IO5a2wU+8H23XSgy/0/qev5wZ5VbaBjrS9HAB41/+dOxVRV5X0Kv5XVC+4MFpW9jOOC8 E4mATUOIZDGIAemlRhW2+e3OmhWGF3TBmrfNXiktkDG7SskaXYO95dWtoRaXg92pguq1 RIJc94FfFy0KyjK2AB1mo+xtHA6f1xcDOOzHlhtu4AwOQcHXHnnchC7u+7zJerKabQ46 LUrqrKVXHTigxSfOHlKgzGx1ni6SEu3YRhsHyeiaNAj/DuvT3QNwJmMG6ny+GEWcurAk bhpA== X-Gm-Message-State: AOJu0Yz1c6cUv7SzkNevgjk6TGKtqiB/pPIhsAbjBdZR4q/abwqk2kYm QCY7+v1LNQ+jObJQbWk+hENzcbSl2B9efs0pcve0kcWQ55YjDJk2Kds2lhZaiPOYs2G1U2YJ/Aq ab0RyPNyRAdtWePvDmJBfGShyFrOaJ1A0BlR1J8wR1/3tgLZ6gck= X-Google-Smtp-Source: AGHT+IHrkMKIHp2QH8IPNBO3AzPXAKVxfC8kdV+wAzPx1Tu5Dtm63hRwAaB+SGtzrEfhHVYo9yGR9u8fw5yldvUIlTI= X-Received: by 2002:a19:3858:0:b0:516:afeb:e27e with SMTP id d24-20020a193858000000b00516afebe27emr1500951lfj.29.1712335242980; Fri, 05 Apr 2024 09:40:42 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: <1c510d08-eaa8-4821-bf1b-6072fe5cb2ff@app.fastmail.com> In-Reply-To: <1c510d08-eaa8-4821-bf1b-6072fe5cb2ff@app.fastmail.com> Date: Fri, 5 Apr 2024 18:40:32 +0200 Message-ID: Subject: Re: [PHP-DEV] Proposal: retrieve line, filename and if user defined for ReflectionAttribute To: Larry Garfield Cc: php internals Content-Type: multipart/alternative; boundary="000000000000e56c7906155c1dcb" From: jwurtz@jolicode.com (Joel Wurtz) --000000000000e56c7906155c1dcb Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Le ven. 5 avr. 2024 =C3=A0 18:04, Larry Garfield a =C3=A9crit : > On Fri, Apr 5, 2024, at 2:20 PM, Joel Wurtz wrote: > >> Would it make sense to not only add this for ReflectionAttribute, but > also Function and/or others? > > > > There may be case where this makes sense but not necessarily in the use > > case that i explain, and don't want to add more to this proposal, it's > > also missing in ReflectionParameter, ReflectionProperty and certainly > > many others if we go on this path then there is a lot of changes to > > apply and will induce more friction for this proposal, i prefer to add > > small parts so we don't deviate from the original use case. > > > >> Do you have an example of how you expect this to be used? I'm having = a > hard time understanding how I'd leverage this. (I maintain an attribute > enhancement library, Crell/AttributeUtils, so I've hit a lot of edge case= s > in attribute design.) > > > > Sure, let's say we have the following class > > > > #[CustomAttribute(foo: 'foo') > > #[CustomAttribute(foo: 'foo') > > class Entity {} > > > > And that later i have something that read those attributes, but i want > > to throw an Exception when multiple attribute defined the same value > > for the foo property (as it should be unique in my use case), i would > > not be able to do that in the constructor since i don't have the > > context of others attributes in this case, so i want to throw a custom > > exception explaining it's caused by the attribute "CustomAttribute" in > > the file "Entity.php" at line 4, as there is the same value in the file > > "Entity.php" at line 3 > > > > If I throw an exception without this message the error will pinpoint to > > where I threw the exception and it may be confusing for the end user, > > by having this he will know where to look and what to modify to make > > its code correct. > > OK, so the idea is you could do something like: > > $rClass =3D new ReflectionClass(Entity::class); > $as =3D $rClass->getAttributes(); > $attribs =3D array_map(fn(ReflectionAttribute $r) =3D> $r->getInstance(),= $as); > $values =3D array_map(fn(CustomAttribute $r) =3D> $r->foo, $attribs); > > if ($values is not unique) { > $msg =3D sprintf('You have too many %s on in file %s on line %d', > Entity::class, $as[0]->getFile(), $as[0]->getLine()); > throw new Exception($msg); > } > > (Or something like that.) > > That works, I suppose, but couldn't that also be done with > ReflectionClass::getStartLine() and ReflectionClass::getFileName()? > > --Larry Garfield > Yes, it could work for a class, but not for a ReflectionProperty or ReflectionParameter also we only have the line for the start of the class, not the line of the attribute, in case where there is a lot of attributes (i.e doctrine entity in a symfony project with validation , serializer, api resource, etc ....) being able to have the correct line is better (even more if you have repeated attributes, and one work but not the other) I'm wondering if this would be useful to also have the offset when there is multiple attribute on the same line (like attribute for ReflectionParameter= ) Joel --000000000000e56c7906155c1dcb Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Le=C2=A0ven. 5 avr. 2024 =C3=A0=C2=A018:04, Larr= y Garfield <larry@garfieldtech= .com> a =C3=A9crit=C2=A0:
On Fri, Apr 5, 2024, at 2:20 PM, Joel Wur= tz wrote:
>> Would it make sense to not only add this for ReflectionAttribute, = but also Function and/or others?
>
> There may be case where this makes sense but not necessarily in the us= e
> case that i explain, and don't want to add more to this proposal, = it's
> also missing in ReflectionParameter, ReflectionProperty and certainly =
> many others if we go on this path then there is a lot of changes to > apply and will induce more friction for this proposal, i prefer to add=
> small parts so we don't deviate from the original use case.
>
>> Do you have an example of how you expect this to be used?=C2=A0 I&= #39;m having a hard time understanding how I'd leverage this.=C2=A0 (I = maintain an attribute enhancement library, Crell/AttributeUtils, so I'v= e hit a lot of edge cases in attribute design.)
>
> Sure, let's say we have the following class
>
> #[CustomAttribute(foo: 'foo')
> #[CustomAttribute(foo: 'foo')
> class Entity {}
>
> And that later i have something that read those attributes, but i want=
> to throw an Exception when multiple attribute defined the same value <= br> > for the foo property (as it should be unique in my use case), i would =
> not be able to do that in the constructor since i don't have the <= br> > context of others attributes in this case, so i want to throw a custom=
> exception explaining it's caused by the attribute "CustomAttr= ibute" in
> the file "Entity.php" at line 4, as there is the same value = in the file
> "Entity.php" at line 3
>
> If I throw an exception without this message the error will pinpoint t= o
> where I threw the exception and it may be confusing for the end user, =
> by having this he will know where to look and what to modify to make <= br> > its code correct.

OK, so the idea is you could do something like:

$rClass =3D new ReflectionClass(Entity::class);
$as =3D $rClass->getAttributes();
$attribs =3D array_map(fn(ReflectionAttribute $r) =3D> $r->getInstanc= e(), $as);
$values =3D array_map(fn(CustomAttribute $r) =3D> $r->foo, $attribs);=

if ($values is not unique) {
=C2=A0 $msg =3D sprintf('You have too many %s on in file %s on line %d&= #39;, Entity::class, $as[0]->getFile(), $as[0]->getLine());
=C2=A0 throw new Exception($msg);
}

(Or something like that.)

That works, I suppose, but couldn't that also be done with ReflectionCl= ass::getStartLine() and ReflectionClass::getFileName()?=C2=A0

--Larry Garfield

Yes, it could work for a class, but not for a = ReflectionProperty or ReflectionParameter also we only have the line for th= e start of the class, not the line of the attribute, in case where there is= a lot of attributes (i.e doctrine entity in a symfony project with validat= ion , serializer, api resource, etc ....) being able to have the correct li= ne is better (even more if you have repeated attributes, and one work but n= ot the other)

I'm wondering if this would be useful to als= o have the offset when there is multiple attribute on the same line (like a= ttribute for ReflectionParameter)

Joel
--000000000000e56c7906155c1dcb--