Re: [PECL-DEV] Introduction & First PHP Extension – Bringing Design by Contract (DbC) to PHP
[email protected] (Andrea M) Wed, 19 Mar 2025 22:31:22 +0100
| Newsgroups | php.pecl.dev |
|---|---|
| Message-ID | <CA+x6MRyxD61N+jdS-ag+dZCCrP6O4EyW_0MYBoVKmt2EBDbHSA@mail.gmail.com> |
--000000000000d5ec700630b8be07
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Thanks for the early feedback.
Yes, that was one of the first things that broke, so I came up with this:
if (invariant_fn) {
zval retval;
zval obj_zval, function_name;
ZVAL_OBJ(&obj_zval, obj);
ZVAL_STRING(&function_name, "__invariant");
// Temporarily restore original zend_execute_ex to prevent infinite
recursion
zend_execute_ex =3D original_zend_execute_ex;
if (call_user_function(CG(function_table),
&obj_zval,
&function_name,
&retval,
0, NULL) =3D=3D SUCCESS)
{
zval_ptr_dtor(&retval);
}
// Restore our custom execution hook
zend_execute_ex =3D invariant_execute_ex;
zval_ptr_dtor(&function_name);
}
I hope this sparks interest.
Best,
Andrea
On Wed, 19 Mar 2025 at 22:24, Yehuda Katz <[email protected]> wrote:
> This looks really interesting. Does it make sure that there is not a loop
> by calling another class method from inside the invariant check?
>
> - Y
>
> Sent from a device with a very small keyboard and hyperactive autocorrect=
.
>
> On Wed, Mar 19, 2025, 4:58=E2=80=AFPM Andrea M <[email protected]=
m> wrote:
>
>> Hi everyone,
>>
>> I started my journey as a LAMP developer back in 2004, working with PHP =
4
>> and MySQL 3. For years, PHP was my daily driver, but toward the end of
>> 2011, I transitioned to JavaScript, gradually writing less and less
>> PHP=E2=80=94until it became just an occasional tool in my stack.
>>
>> That changed with *beyond-tabs.com <http://beyond-tabs.com>*. Through
>> this project, I found myself re-embracing PHP, and, thanks to this
>> community, I also discovered *Design by Contract (DbC)*=E2=80=94a paradi=
gm that
>> immediately resonated with me. Now, I want to take the next step and aut=
hor
>> my very first PHP extension: *Invariant PHP
>> <https://github.com/andreamancuso/invariant-php>*, bringing DbC
>> principles to the language.
>>
>> Beyond just being an extension, I see this as a *proof of concept*=E2=80=
=94a way
>> to demonstrate the value of DbC in PHP and potentially spark a conversat=
ion
>> about native support in future PHP versions. I=E2=80=99m eager to learn =
from this
>> group, get feedback, and hopefully contribute something meaningful to th=
e
>> ecosystem.
>>
>> Looking forward to your guidance and insights!
>>
>> Best,
>> Andrea
>>
>
--000000000000d5ec700630b8be07
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr"><div>Thanks for the early feedback.</div>=
<div><br></div><div>Yes, that was one of the first things that broke, so I =
came up with this:<br><br>
<div style=3D"color:rgb(204,204,204);background-color:rgb(31,31,31);font-fa=
mily:Consolas,"Courier New",monospace;font-weight:normal;font-siz=
e:13px;line-height:18px;white-space:pre"><div><span style=3D"color:rgb(197,=
134,192)">if</span><span style=3D"color:rgb(204,204,204)"> (</span><span st=
yle=3D"color:rgb(156,220,254)">invariant_fn</span><span style=3D"color:rgb(=
204,204,204)">) {</span></div><div><span style=3D"color:rgb(204,204,204)">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(78,201,176)">zv=
al</span><span style=3D"color:rgb(204,204,204)"> </span><span style=3D"colo=
r:rgb(156,220,254)">retval</span><span style=3D"color:rgb(204,204,204)">;</=
span></div><div><span style=3D"color:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=A0=
=C2=A0 </span><span style=3D"color:rgb(78,201,176)">zval</span><span style=
=3D"color:rgb(204,204,204)"> </span><span style=3D"color:rgb(156,220,254)">=
obj_zval</span><span style=3D"color:rgb(204,204,204)">, </span><span style=
=3D"color:rgb(156,220,254)">function_name</span><span style=3D"color:rgb(20=
4,204,204)">;</span></div><div><span style=3D"color:rgb(204,204,204)">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(86,156,214)">ZVAL_=
OBJ</span><span style=3D"color:rgb(204,204,204)">(</span><span style=3D"col=
or:rgb(212,212,212)">&</span><span style=3D"color:rgb(156,220,254)">obj=
_zval</span><span style=3D"color:rgb(204,204,204)">, </span><span style=3D"=
color:rgb(156,220,254)">obj</span><span style=3D"color:rgb(204,204,204)">);=
</span></div><div><span style=3D"color:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color:rgb(86,156,214)">ZVAL_STRING</span><=
span style=3D"color:rgb(204,204,204)">(</span><span style=3D"color:rgb(212,=
212,212)">&</span><span style=3D"color:rgb(156,220,254)">function_name<=
/span><span style=3D"color:rgb(204,204,204)">, </span><span style=3D"color:=
rgb(206,145,120)">"__invariant"</span><span style=3D"color:rgb(20=
4,204,204)">);</span></div><br><div><span style=3D"color:rgb(204,204,204)">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(106,153,85)">//=
Temporarily restore original zend_execute_ex to prevent infinite recursion=
</span></div><div><span style=3D"color:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color:rgb(156,220,254)">zend_execute_ex</s=
pan><span style=3D"color:rgb(204,204,204)"> </span><span style=3D"color:rgb=
(212,212,212)">=3D</span><span style=3D"color:rgb(204,204,204)"> </span><sp=
an style=3D"color:rgb(156,220,254)">original_zend_execute_ex</span><span st=
yle=3D"color:rgb(204,204,204)">;</span></div><br><div><span style=3D"color:=
rgb(204,204,204)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:r=
gb(197,134,192)">if</span><span style=3D"color:rgb(204,204,204)"> (</span><=
span style=3D"color:rgb(86,156,214)">call_user_function</span><span style=
=3D"color:rgb(204,204,204)">(</span><span style=3D"color:rgb(86,156,214)">C=
G</span><span style=3D"color:rgb(204,204,204)">(function_table),</span></di=
v><div><span style=3D"color:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0</span><span style=3D"color:rgb(212,212,212)">&</span><span s=
tyle=3D"color:rgb(156,220,254)">obj_zval</span><span style=3D"color:rgb(204=
,204,204)">,</span></div><div><span style=3D"color:rgb(204,204,204)">=C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:rgb(212,212,212)=
">&</span><span style=3D"color:rgb(156,220,254)">function_name</span><s=
pan style=3D"color:rgb(204,204,204)">,</span></div><div><span style=3D"colo=
r:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=
=3D"color:rgb(212,212,212)">&</span><span style=3D"color:rgb(156,220,25=
4)">retval</span><span style=3D"color:rgb(204,204,204)">,</span></div><div>=
<span style=3D"color:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0</span><span style=3D"color:rgb(181,206,168)">0</span><span style=3D"col=
or:rgb(204,204,204)">, </span><span style=3D"color:rgb(86,156,214)">NULL</s=
pan><span style=3D"color:rgb(204,204,204)">) </span><span style=3D"color:rg=
b(212,212,212)">=3D=3D</span><span style=3D"color:rgb(204,204,204)"> </span=
><span style=3D"color:rgb(79,193,255)">SUCCESS</span><span style=3D"color:r=
gb(204,204,204)">)</span></div><div><span style=3D"color:rgb(204,204,204)">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 {</span></div><div><span style=3D"color:rgb(204=
,204,204)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"=
color:rgb(220,220,170)">zval_ptr_dtor</span><span style=3D"color:rgb(204,20=
4,204)">(</span><span style=3D"color:rgb(212,212,212)">&</span><span st=
yle=3D"color:rgb(156,220,254)">retval</span><span style=3D"color:rgb(204,20=
4,204)">);</span></div><div><span style=3D"color:rgb(204,204,204)">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 }</span></div><br><div><span style=3D"color:rgb(204,20=
4,204)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:rgb(106,153=
,85)">// Restore our custom execution hook</span></div><div><span style=3D"=
color:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"c=
olor:rgb(156,220,254)">zend_execute_ex</span><span style=3D"color:rgb(204,2=
04,204)"> </span><span style=3D"color:rgb(212,212,212)">=3D</span><span sty=
le=3D"color:rgb(204,204,204)"> </span><span style=3D"color:rgb(220,220,170)=
">invariant_execute_ex</span><span style=3D"color:rgb(204,204,204)">;</span=
></div><div><span style=3D"color:rgb(204,204,204)">=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color:rgb(220,220,170)">zval_ptr_dtor</span><span=
style=3D"color:rgb(204,204,204)">(</span><span style=3D"color:rgb(212,212,=
212)">&</span><span style=3D"color:rgb(156,220,254)">function_name</spa=
n><span style=3D"color:rgb(204,204,204)">);</span></div><div><span style=3D=
"color:rgb(204,204,204)">=C2=A0 =C2=A0 }</span></div></div>
</div></div><div><br></div><div>I hope this sparks interest.</div><div><br>=
</div><div>Best,</div><div>Andrea<br></div><div><br></div><div class=3D"gma=
il_quote gmail_quote_container"><div dir=3D"ltr" class=3D"gmail_attr">On We=
d, 19 Mar 2025 at 22:24, Yehuda Katz <<a href=3D"mailto:[email protected]=
t">[email protected]</a>> wrote:<br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><div dir=3D"auto"><div>This looks really interesting. D=
oes it make sure that there is not a loop by calling another class method f=
rom inside the invariant check?=C2=A0</div><div dir=3D"auto"><br></div><div=
dir=3D"auto">- Y</div><div><br></div><div>Sent from a device with a very s=
mall keyboard and hyperactive autocorrect.</div></div><br><div class=3D"gma=
il_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, Mar 19, 2025, 4:58=
=E2=80=AFPM Andrea M <<a href=3D"mailto:[email protected]" targ=
et=3D"_blank">[email protected]</a>> wrote:<br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px s=
olid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">
<p>Hi everyone,</p>
<p>I started my journey as a LAMP developer back in 2004, working with PHP =
4 and MySQL 3. For years, PHP was my daily driver, but toward the end of 20=
11, I transitioned to JavaScript, gradually writing less and less PHP=E2=80=
=94until it became just an occasional tool in my stack.</p>
<p>That changed with <b><a href=3D"http://beyond-tabs.com" rel=3D"noreferre=
r" target=3D"_blank">beyond-tabs.com</a></b>. Through this project, I found=
myself re-embracing PHP, and, thanks to this community, I also discovered =
<b>Design by Contract (DbC)</b>=E2=80=94a paradigm that immediately resonat=
ed with me. Now, I want to take the next step and author my very first PHP =
extension: <b><a href=3D"https://github.com/andreamancuso/invariant-php" re=
l=3D"noreferrer" target=3D"_blank">Invariant PHP</a></b>, bringing DbC prin=
ciples to the language.</p>
<p>Beyond just being an extension, I see this as a <b>proof of concept</b>=
=E2=80=94a way to demonstrate the value of DbC in PHP and potentially spark=
a conversation about native support in future PHP versions. I=E2=80=99m ea=
ger to learn from this group, get feedback, and hopefully contribute someth=
ing meaningful to the ecosystem.</p>
<p>Looking forward to your guidance and insights!</p>
<p>Best,<br>
Andrea</p>
</div>
</blockquote></div>
</blockquote></div></div>
--000000000000d5ec700630b8be07--