PHP 8.4 with Sabatino & Brent (Property hooks, Asymmetric visibility, Lazy objects and more)
In this conversation, Brent will bring me up to speed with the exciting new features of PHP 8.4. We discuss the new features introduced in PHP 8.4, including lazy objects, property hooks, asymmetric visibility, and the deprecation of implicit nullable types.
Huge shout-out to Brent from PHP Annotated & stitcher.io for joining me in this conversation!
Read more about new features in PHP 8.4 on Brent's blog over at: https://stitcher.io/blog/new-in-php-84
AI Transcript
Sabatino Masala (00:25)
Alright, thank you so much for joining me, Brent, in our PHP 8.4 discussion.
Brent (00:32)
Yes. Hey, Sabatino. I'm glad to be here and such an exciting topic to talk about. When it's about PHP 8.4, I'm here to share my opinion and thoughts about it.
Sabatino Masala (00:38)
Yeah, indeed, indeed.
Yeah, I think you're one of the biggest PHP names in the game, so I'm very honored to be talking to you about PHP 8.4.
Brent (00:53)
Well, if all goes well, we'll be talking a little bit more after this one as well, because we want to make this into a kind of series, right?
Sabatino Masala (01:00)
Yes, exactly. I don't know if people know, but we are both from Belgium. So it's a small country in Europe. And Brent actually did a reach out to me over the summer and we got talking and one thing led to another. And yeah, here we are starting our own podcast. Trying to exactly. Yeah. Indeed, indeed. But yeah, let's dive right in.
Brent (01:05)
Mm.
trying to but we'll see if people find it interesting enough.
Right, yeah, PHP 8.4. Wow, have you tried it out?
Sabatino Masala (01:32)
I have, and I also have tried your framework Tempest. So yeah, I was actually very surprised. I'm a very... I don't like change, so I'm very set in my ways. So I started your framework with an open mind and I actually was kind of surprised how nice it was. And I mean it the best way. So it's so easy and...
Brent (01:37)
yeah.
Sabatino Masala (02:01)
The way you use attributes in PHP is actually very nice to indicate the routes. I really like the simplicity and what you've done there.
Brent (02:10)
Wow, thank you. It's like...
The thing with PHP is that it's changed so much and I just wanted to build something with modern PHP and it kind of snowballed from there. But maybe Tempest could be a topic for a podcast on its own because there are lots of interesting things to say about that. It's interesting that you mentioned change and the kind of...
Sabatino Masala (02:22)
Yeah.
Yeah, indeed. Yeah.
Brent (02:39)
hesitation towards change because I feel that as well. And even with every PHP release, I'm super excited about it. But at the same time, I'm like, no. Okay, that's we'll have to put in the work. have to update my my force configurations for, you know, just my digital ocean droplets, they have to be updated. How you have to go through the deprecation notices. And even though I think they are really great and helping us move forward, it's still like
Sabatino Masala (02:57)
Yeah, exactly.
Brent (03:08)
Okay, let's put in the work because... And then you have to deal with packages being updated or not updated. It's actually a problem we're running into with Tempus now because one of the things we said when we started, like for real, this was a year ago, something like that. And we knew upfront that PHP 8.04 would be the...
Sabatino Masala (03:15)
Exactly.
Brent (03:37)
the lowest release we wanted to support. So we were working towards a year in the future, basically, and then released something that doesn't have support for any old PHP versions. Getting closer to the PHP release, which was, let me check, a month ago, right? And well, two weeks ago, three weeks ago, something like that.
Sabatino Masala (03:46)
Mm-hmm.
Yeah, exactly.
Mm-hmm.
Brent (04:06)
You know, it started to dawn on me that it's so much work to, if you like, want to update a PHP 8.3 code base that embraces all modern things up until that point, and now when you switch to PHP 8.4, most of it is backwards compatible. But if you really want to use the new features, are quite a lot of new things there. Yeah.
Sabatino Masala (04:28)
I can imagine. yeah. Maybe a bit of topic, but how long have you been developing in PHP for?
Brent (04:37)
professionally 10 years and like on my own for 14 I think something like that
Sabatino Masala (04:40)
Yeah, all right.
And wow. So what's your earliest PHP version?
Brent (04:50)
Yeah, well, like the thing I remember, like, I'm aware of that I ran into it was the new, the short array syntax, array syntax arrived. But it's not really all that early. I mean, that was PHP 5.4, 5.5, I don't know, something around that time. And I remember because I was doing my internship. So last year of college, I was doing my internship at like,
Sabatino Masala (05:01)
wow, yeah, okay.
Yeah.
Brent (05:19)
symphony, CMS building company, they were called Kunstmann, I don't know if they exist still, but they were pretty big back then and I was tasked with making some kind of symphony bundle for Google Analytics dashboard in their CMS, something like that.
Sabatino Masala (05:25)
Okay, yeah.
Brent (05:37)
And I was writing PHP and I used short array syntax because I was like, this is great. It requires so much less typing and it's so much cleaner. And then code review came in. Yeah, you cannot use it because this is the latest PHP version. we actually, yeah, we still need to support all older versions, which is my very first time. was like, this is stupid. just want to only support the latest PHP version. On the other end, I mean, I totally get it.
Sabatino Masala (05:56)
Okay.
Ha
Brent (06:07)
once a project is used you cannot just start bumping versions well maybe you can but there's nuance to this I mean you need to find a balance there so but with Tempest it's really really easy because you know it's just starting from scratch so there's no one using it now
Sabatino Masala (06:16)
Yeah, exactly.
Yeah, indeed. Yeah. So my first PHP version was also, think, PHP five point. I think it's the same one you mentioned. And I actually started out as a Flash game developer and I wanted to have like a little high score board that was set on a server. And I found a little script online that took like a post request and would store it in a database. And that was actually my first interaction with PHP, I think.
Brent (06:37)
wow.
Sabatino Masala (06:53)
maybe like 15 years ago, 14 years ago. And I do distinctly remember the short open syntax. it was a configuration in php.ini and that one bit me in the ass multiple times because I was like, yeah, it's less typing work, but it's not a default configuration. So you deploy it on your server on digital ocean droplet, and then you get blank page.
Brent (06:58)
Hmm.
Yeah
Yeah.
Yeah.
Hmm.
around.
Sabatino Masala (07:20)
And it was all because of the short open syntax. So yeah.
Brent (07:21)
Yeah.
PHP has these weird edge cases where there's one very specific thing in Tempest that I really had to work around with. If you have a class, I don't know why this happens, but if you have a class and the namespace doesn't match PSR for the format your Composer Autoloader basically requires, then somehow, and I don't know why, PHP gives an error
that the class was already declared and you cannot re-declare it again and it doesn't give any more information about it and it's super confusing and I've ran into this problem three or four times in Tempus and I always fixed it. I have this on a live stream somewhere. It took me half an hour to an hour to debug the issue the first time and then I finally found it. It's like classic programming. Like, it's so stupid.
Sabatino Masala (07:59)
yeah.
Such a simple mistake, yeah.
Brent (08:25)
wrong namespace, but then I forgot about it. And I know I mentioned on the livestream, I said something like, I need to take a note of this. And I didn't. you know, just a couple of weeks later, wasn't all that much later, but I ran into the same problem. And I did the same debugging session. I was like, I know there is there is a solution for this somewhere, but I can't remember.
Sabatino Masala (08:46)
You
Brent (08:53)
man, and so it came to a point because this is a fatal error in PHP and you cannot catch it. So in Tempus, what I've just done is the very first line when the kernel boots is just add a custom error handler, right? Or shutdown function, I don't know. And it checks whether the message is like, cannot re-declare class. And if that's the case, just append a string like, did you forget the namespace? Like just as a note for myself because...
Sabatino Masala (08:57)
Indeed.
Nice.
Brent (09:19)
And I don't understand why PHP does this. The error doesn't make any sense. doesn't give like any trace. cannot, like, it doesn't say which file, in which file the other class with the same name was declared, of course, because it's in the same file. mean, when you say it like that, it makes sense. But if you run into this error and so many, like literally hours I've lost on this.
Sabatino Masala (09:43)
Yeah, I can imagine. It's kind of like Googling an error and reaching your own Stack Overflow post where you ask the same question. Yeah.
Brent (09:50)
Yeah, exactly, exactly. So yeah, PHP, it still has its quirks, but it's like if I compare it to 10 years ago when I started out, what a great language it has become. I mean, there are many things we can say that it's still lacking, but wow, I was amazed.
Sabatino Masala (10:12)
I truly love PHP because it's like you say, there are other languages that have other features like Node.js with the async stuff that PHP is lacking, but I don't miss it in PHP because you have things like queues and Laravel, which allows you to create asynchronous jobs on a queue, which allows you to dispatch asynchronous jobs on a queue. So I truly don't miss things like that.
Brent (10:30)
Hmm.
Yeah, and then there are extensions like Swool and ReactPHP. I mean, yeah, also, they're pretty cool. And we need to keep our eye on FrankenPHP. think that's going places. So, know, PHP 804, it's a pretty big release. It's the biggest release, in my opinion, since PHP 7.4. And that's because in 7.4, we got typed properties. Can you imagine?
Sabatino Masala (10:42)
Exactly, Yeah, Franken-PHP.
Yeah, definitely.
Well.
Brent (11:06)
I sometimes scroll through my blog pre-PHP 7.4 and I have these code samples and it didn't have typed properties in classes. It's crazy, right? So I would say 8.4 is definitely the biggest release since 7.4. And that's like, I mean, there have been many great features in 8, 8.1, 8.2, 8.3 was really, I don't know, not really that exciting.
Sabatino Masala (11:17)
It's crazy. Indeed.
Yeah, that was a very minor release, have a feeling.
Brent (11:36)
but.
Yeah, yeah, it was also like the first year of the foundation. So I guess it made sense that they still had to like pick up some speed and trying to figure out, yeah, okay, what's the direction we want to go in? And then this year, wow, all the things we've got.
Sabatino Masala (11:43)
Mm-hmm.
Yeah, it was a very hyped release. And like I said in the introduction, I had a bit of an accident a few weeks ago where I broke my elbow. So I kind of missed the entire release. I was recovering from my injury. So I kind of missed the entire release. And that's where this idea came from. a Sabatino and Brent should hop on a podcast and talk about PHP 8.4 where Sabatino doesn't have the experience of Brent.
Brent (12:03)
Mmm.
Sabatino Masala (12:20)
and he's gonna be amazed by all the new features of PHP 8.4.
Brent (12:21)
Yeah, well, but you did already play a bit with Tempest dance, so you got a little bit of a feeling. I have to say like Tempest hasn't been updated to 8.04 entirely yet. It's so much work. And you'll probably understand why when I go through it, because yeah, well, it will become clear. Do you want me to share my favorite feature first of PHP 8.04? You're going to be mind blown. You're going to be mind blown.
Sabatino Masala (12:26)
A little bit, a little bit, yeah. Indeed.
Definitely, yes, let's start there.
Brent (12:52)
It's such a simple thing. But remember, if you want to create a new object and then call a method on it, which is something I pretty often do, actually, you had to wrap it in braces in brackets, like the new invocations are like new user.
Sabatino Masala (13:10)
yeah, yeah. So new user. Yeah.
Brent (13:14)
within brackets and then save for example, call save on it. That's a lot of like example, but I often use it with actions, action style classes, stuff like that. yeah, yeah, yeah, yeah, yeah, people didn't like it.
Sabatino Masala (13:21)
Yeah, I saw your latest video about actions. Very interesting, by the way. Yeah, it was, it was, I opened the comment section. It was a bit of a mixed bag in there, but I liked it. I liked it. I saw your blog post. It was like an older blog post. saw it and then I liked the pattern. I don't know why people are so upset about it, but yeah.
Brent (13:29)
Okay, thank you.
Yeah, it's really... I overacted a little bit. I said I invented it, which I shouldn't have said. I mean, it's okay. I've been on YouTube for a couple years now. You get used to the comments, but I'm still recovering from that one, honestly. No, but my favorite feature definitely are the... It's such a stupid thing, but like, you don't need those brackets anymore. So you just say new, blah, blah.
Sabatino Masala (13:53)
Mm-hmm.
haha
Yeah, the omission of the brackets. So you can say new user, new user and just append like set, set name without the bracket. That's actually very cool. Yeah.
Brent (14:13)
Exactly. Yeah, it's such a small thing, but I mean, it's great as well realizing that PHP is getting more and more of these quality of life features and not just, you know, if we would get async or generics or stuff like that, those will be really like big features. But we're at a point where, okay, there are still a couple of big things open, but there's room and space for like
fine-tuning the syntax of the language. And it's just becoming so much more convenient. And PHP is pretty cool in being able to do it all backwards compatible. But yeah, I'm just, like, there are many features here in 8.4 that people could say, yeah, but we could already do that before. Like, it doesn't really make a difference. And I always point to attributes. Because, like, I've heard this argument before from people.
Sabatino Masala (14:50)
Yeah, exactly.
Brent (15:12)
where they say, yeah, but this is just syntactic sugar. It's useless. We don't need it in PHP. And then I point to attributes. mean, everything that attributes are doing now was already possible with DogBlocks, right? mean, Symphony, Doctrine, they did it like when I was doing Symphony 10, 14-ish years ago, 10 years. They were already using annotations. They were called annotations back then with DogBlocks, right?
Sabatino Masala (15:22)
Exactly.
Brent (15:42)
So we could already do it. Why do we need attributes, which is just syntactic sugar or a better way of writing it? Well, I mean, everyone loves attributes. think maybe not everyone loves them, but all big frameworks are embracing them. So, I mean, whether you like them or not, the majority, apparently there's enough of a want for it that frameworks decide, okay, let's embrace attributes. That's one example. Constructor property promotion is another one. we could already do the same things.
Sabatino Masala (15:57)
True.
Brent (16:12)
but it's just a little more convenient. It makes me more happy being able to write PHP and that's a good thing. So.
Sabatino Masala (16:14)
Exactly.
Exactly, exactly. It's funny you mentioned the promotion, the constructor. What was it called? The constructor property promotion. Yeah. So because that one took a lot of boilerplate code away. Before you would have like a new user constructor, takes a first name and last name. And then you say this first name equals first name. This last name equals the last name. You can omit that entirely. It just saves so much code.
Brent (16:21)
Yeah. Property promotion.
Yeah.
Yeah, yeah, it's just like, and we're so used to it now again, like, constructor property promotion was such a big thing. Like, you cannot imagine having to do all that work. And you could generate the code to your ID and stuff like that. But it was just so much text to scroll through with no meaning, no added value. So yeah, funny thing about constructor property promotion, like under the hood, it's actually just...
Sabatino Masala (17:02)
Exactly, exactly.
Brent (17:09)
like using that syntax and then pulling it apart and generating a PHP file. Well, it's not a PHP file, if I understand. They go directly to upcodes, of course. they just generate the code as if it wasn't using promoted property. So it's really just syntactic sugar. It's transpiling on the fly. Yeah.
Sabatino Masala (17:26)
Okay, that's actually very interesting. Yeah, very cool. Very cool. It's like I did some Objective-C and Swift in a past life. And they had this thing, this concept called bridging header, where you could expose things from Objective-C to Swift and vice versa. And that's actually the same thing it would generate like this magic file, Apple would generate this magic file or Xcode would, which
Brent (17:34)
Hmm?
Yeah.
Okay.
Sabatino Masala (17:52)
exposes things to the Objective-C world from Swift and vice versa. So that's actually very reminiscent of the thing that happens here with the opcode or the in-between generation in PHP.
Brent (17:58)
you
Yeah. Yeah, it's really, really interesting topic. But that's not what PHP 8.4 is about. I don't know if we've been now talking about the PHP and haven't. Well, I mentioned that one small feature, but there are so many more things. So maybe let's go through my list here. The first thing that besides like the brackets being omitted are property hooks. Have you heard of property hooks? Okay.
Sabatino Masala (18:30)
I haven't actually. I've seen some blog posts, but I restrained myself to not click on it to learn exactly. Exactly.
Brent (18:37)
Right, you want it to be like really surprised and mind blown. Property hooks, are like with every PHP feature, there are opponents and proponents for it. like, I'm such a big fan of this. the RFC had such a nice tagline. Well, it wasn't really a tagline. It was like sprinkled in somewhere in between. the goal of this RFC was for it to be not to be used like...
most of the time. the goal of property hooks is that people don't really use them, only as like a last resort basically. so here's the thing. You make a property on a class, right? And you want some kind of encapsulation and certainty that like people cannot suddenly change the property from the outside or do weird things with it. So...
Sabatino Masala (19:18)
Okay.
Mm-hmm.
Okay.
Brent (19:34)
The standard pattern here is to have a private property with a public getter, public setter maybe. And that makes it so that you have two entry points. Well, one outgoing entry point, that's not an entry point, but it doesn't matter. You have two points where you can hook into, right? You have the getter and the setter. And if you need to do things with the property, if you need to do validation, for example, if you need to make sure that when you...
Sabatino Masala (19:40)
Mm-hmm.
Okay.
Brent (20:03)
when a user sets a value for a specific property from the outside and you want to add validation, you have that method in place. And so what often happens if people want this proper kind of encapsulation, when they code and build their classes, they just have their private properties, getters and setters all in place and you have just a big file with lots of code, right?
Sabatino Masala (20:29)
Okay, let's maybe make an example here. So we have a user class, it takes an email address in the constructor, then that's going to be private, right? So the property is going to be private. And we have a setter on the user set email, it's going to do like some validation, make sure it's a valid email address, you cannot add gibberish. And then only if the email address is valid, it will be set on the property. All right.
Brent (20:35)
Mm-hmm.
second.
Right. And so, before PHP 804, you just always have these getters and setters in place in case you would need them in the future because if you didn't have getters and setters in place, you would have to make the property public. And then people can do whatever they want with it. So lots of overhead. Getters, setters, very boring code. And oftentimes not.
Sabatino Masala (21:12)
Exactly.
Mm-hmm.
Brent (21:23)
not really needed unless you need these extra validation steps or maybe you want to do something with calculated properties where you have the full name, get full name, it's just concatenating the first name and the last name, stuff like that. And so with property hooks, it turns the problem kind of around. It says, OK, let's start with public properties. All properties are publicly available.
Sabatino Masala (21:31)
Okay.
Yeah, all right.
Brent (21:50)
And in case you need to add some validation for the edge cases, or in case you need like a virtual property, you could add hooks for them. And hooks, just, it's like a special kind of syntax. You have the property and you open curly brackets. Since this is an audio format, we have to describe it a little bit. But you open the curly brackets there. And then the property gets kind of a body, a function body, sort of. But there's a special kind of syntax there.
Sabatino Masala (22:10)
Yeah, indeed.
Okay.
Brent (22:20)
And you can define a get hook for it and a set hook for it. You don't have to define both of them. There are shorthands for it. They look like functions with like a little bit kind of different syntax, but you'll get used to it if you've written a couple of properties. The things there are optional, right? So only if you need them, you can add the hooks. And the beauty is that they don't add methods anymore on the class.
Sabatino Masala (22:24)
Alright.
Mm-hmm.
Brent (22:50)
They kind of act like magic getters and setters, but like properly tied to a property. And they will be called, like the get hook will be called whenever someone tries to set a value. No, get the value from the class. And the set hook will be called like when someone tries to override it from the outside. And then you have these places, these hooks, where you can add your email validation, where you can
Sabatino Masala (23:05)
Get a value.
Okay.
Brent (23:19)
like concatenate the first name and the last name if you need to. But they are completely optional. So you start, like in 95 % of the cases, you just start with public properties, no more getters, no more setters. you have the certainty that if at some point you need to add some extra logic here, you can just define the hooks and they will hook into.
the normal syntax. There's no more distinction anymore between like, you need a method in place before you can access or read the property. And you just, you make sure you have it in place because just in case for the future, know, no, the idea of property hooks is that properties become more of a first-class citizen of the public API of a class and...
get and set hooks, offer like, yeah, hooks and ways to deal with that in a more dynamic way.
Sabatino Masala (24:18)
It's very interesting. Can you bypass the setter in any way? Is there a way, for example, in Objective-C, I remember you had setters and getters, and if you would prefix the variable or the property with an underscore, if I'm not mistaken, you would bypass the set. That's not possible. So not even from within the class, you cannot override the set. You always go through the set property hook.
Brent (24:36)
no, that's not possible.
Yeah, if I yeah, yeah, yeah. Don't like quote me 100 % on that. But I'm fairly certain that's the case. but I do think that something's possible with reflection. I'm not sure about it. But it was a really long, long RFC. I read through it twice. It was like, it was it took an hour to read through or something like that. was really, but it was really good. They covered a lot of edge cases. So yeah, it's
Sabatino Masala (24:48)
Okay.
Okay, alright.
But that's an interesting feature indeed. And you could have entirely virtual properties if I'm not mistaken. For example, the full name you mentioned, it could only have a getter, for example, which could concatenate the first name and the last name. It would have no setter and that's totally valid, right? All right.
Brent (25:17)
Yeah.
Yep. Yep.
Yeah, yeah, yeah, so a property with only a get hook basically means it's a virtual property. It doesn't really exist, but it just calculates something on the fly. As soon as it has a set hook, then there will be some memory assigned for it, and you'll be able to store stuff in it.
Sabatino Masala (25:46)
Okay.
And is a virtual property the correct term or is it a property? Okay, all right, so virtual property. Very cool, it's a very cool feature. I will definitely use that.
Brent (25:52)
Yeah, it was used in the RFC.
Yeah. I think they used it already for it as well. Let me see. Virtual property or something like it has no, no, it's like backing value because, yeah, that was like a property with a backing value means it's not a virtual property. That was like the two words that were important.
Sabatino Masala (26:04)
computed property maybe.
Okay. Okay. And the internal, so you mentioned that no memory would be allocated. only memory would be allocated if it has a setter, right? If it has a set property hook.
Brent (26:24)
Yeah, if I understood correctly. But again, don't worry. I'm not an internal developer.
Sabatino Masala (26:28)
Yeah. No, no, but it's very interesting to hear about those internals you read through the RFC. you have some idea how it works. Yeah.
Brent (26:35)
Yeah, a while ago, a while ago. I also sat down with Larry, the creator of the RFC, did a live stream with him to talk about it. And what I learned there, because some people might be wondering about this as well, is that, like, what's the impact on performance? Because, like, you feel these hooks are a little bit...
Sabatino Masala (26:43)
Okay, very cool.
Brent (26:59)
similar to Magic Getters and Setters but in a more convenient way. Magic Getters and Setters are less performant compared to just normal property access. And good thing with this RFC is that if a property doesn't have any hooks defined it will just be normal property. You can access and read and write to it just normal and there will be no performance overhead there. If you use property hooks there will be a small performance overhead.
Sabatino Masala (27:15)
Okay.
Okay.
Brent (27:27)
just for the properties that have hooks defined. But that overhead is less than if you were to use magic getters and setters. Yeah. Yeah. Yeah, it actually took some work because, yeah, I remember something around, I think it was the beta period, June, July, something like that, where they ran into some performance issues when people started testing it and they had to do some more effectoring.
Sabatino Masala (27:29)
Okay.
All right, that's interesting that they were able to optimize it a bit. Yeah, very cool. Yeah, I can imagine.
Brent (27:55)
But in the end it worked out. It's really cool. Now I haven't mentioned the most important part of this RFC actually, because in my case I have very little use cases for like hooking into specific properties. But the cool thing is with this RFC came the ability to define property hooks on interfaces. But that means...
that you can basically have an interface define a property. And that makes sense, right? Because properties are now, like I mentioned, something more than just private state, they are part of the public API. So it makes sense that they are available on interfaces. And that means that in an interface, you can define a property, but it needs a hook, right? On the interface, it needs a hook. And you can choose whether it has a get hook, a set hook, or both, right?
So the interface defines that. But the cool thing is then in the class, you can just still define the normal property without hooks because there is like a normal get and set access if it's a public property. And that just works. So you don't really need the hooks, but on the interface, you use that syntax to indicate like this public property needs getter access, setter access, both.
Sabatino Masala (29:07)
Okay, all right, all right, all right.
That's actually very interesting.
Brent (29:23)
Yeah, and this is like, it has a huge impact because I always use the example in Tempus of the request class, which has lots of properties like the methods, the request methods, the URI, the request body, know, all these kinds of things. And in Tempus, we program to an interface. So there's an implementation of request, but...
Like most of the time people are using interfaces. So you need to define getters on the interface because you want to be able to access that data from the outside without having to know like I have like this specific implementation of requests that I'm working with. So yeah, those kinds of interfaces and this happens a lot in Tempest, they are riddled with boring getters and you then have to implement them like get method.
return this method, getBody, return this body. It goes on and on. But now, now we'll be able to just define the properties and then have public properties on the concrete implementations and be done with it. So that's really powerful. In my case, like the getHook is probably the most important because this is also a thing we do in Tempus is most of the time we have read-only classes or...
you know, use immutable methods. We don't really change data once it's unless it's for really internal state within a class. But if we're talking about something like a request or, you know, most of the thing, value objects, data transfer objects, you know, you'd set data once with the constructor and then you never change it. the interface doesn't really need to specify anything when it comes to setters, only forgetters.
Sabatino Masala (31:04)
Mm-hmm.
Brent (31:19)
Yeah, it's really great, but it's also a lot of work because we've written a lot of interfaces with a lot of methods and I have to refactor all of those. So yeah, that's what we're working on.
Sabatino Masala (31:23)
I can imagine, yeah.
Yeah, but it's very cool. So I have another question with regards to the, for example, the setter implementation of your property. Is there a way to reuse setters across different properties? For example, you have, there's no way. So you cannot say like, hey, my first name or my full name has to go to this magic thing. And I don't know what else needs to concatenate something has to do this, the same magic thing.
Brent (31:37)
Mm.
Mm.
Sabatino Masala (32:00)
There's no way to... Okay.
Brent (32:00)
No, it's not possible. You can call class instance methods within the hooks. So that's one way you could like move shared logic towards one method and then call that method from multiple hooks. But it's not really super reusable. It would, yeah.
Sabatino Masala (32:14)
Mm-hmm.
Yeah, obviously indeed.
Okay.
Brent (32:29)
There might be some room for improvement here, but honestly, like the RFC set as well, its goal is to be not used all that much, but just have the fact that the possibility is there means that people can ditch all or most getters and setters because, know, just in case I need it in the future, it's possible with just the property access syntax and I don't need a dedicated method for it.
Sabatino Masala (32:31)
Mm-hmm.
Okay, I have the possibility to...
Mm-hmm.
Yeah, but it's a very interesting feature. I see myself using it all the time. I'm wondering how a framework like Laravel would adapt things like this.
Brent (33:00)
Mm.
Yeah, that's difficult, right? Because if you look at eloquent models, they have accessors and mutators where you can hook into a specific property. They have casters as well. In theory, you could change all of that syntax to make use of property hooks, but imagine the breaking change. That's not going to happen for a couple of years. mean, Laravel is now starting to add attributes everywhere or in most places, except for routes. I don't know.
Sabatino Masala (33:15)
Mm-hmm.
Mm-hmm, I saw.
Brent (33:34)
I talked about this with think Christoph Rumpel. I asked him, do you have any plans for route attributes now? No, no, no, no, that's...
Sabatino Masala (33:37)
Okay.
But that's the thing that I found interesting in Tempest because you have like the route attribute. So people who haven't used Tempest yet. you have like a class that defines attributes, for example, route slash, for example, the route route. The route route. Wow. And then you have your methods that gets executed when you visit that route. And to me, that was like mind blowing. That was like a mind blowing moment to have this simplicity.
Brent (33:58)
Yeah. Yeah.
So we'll try.
Yeah.
Sabatino Masala (34:13)
But I can see like a framework like Laravel, if you have a lot of files, it's going to be very difficult to keep track of all your routes.
Brent (34:19)
Yeah, but that's like, that's, that's the argument, right? Against route attributes that it doesn't scale. That's, that's really like, I don't know the right word of fallacy, something like that. like you can, the argument for, for route files in Laravel is that, yeah, I just have to open a file and can see all my rights. So I worked in Laravel apps that had like thousands of routes. yeah.
Sabatino Masala (34:26)
Mm-hmm.
Mm-hmm.
Brent (34:48)
That's not, that doesn't scale for one. So you split it up in different files anyway, because like having one file, API admin section, user phasing section, and some, I don't know, lots of stuff. So it doesn't really scale all that well in a single file either. That's one thing. Second thing is you have like the artisan routes, route list commands, I think.
Sabatino Masala (34:55)
Yeah, you have like your API, your web, your, yeah, exactly.
Exactly.
Brent (35:17)
that already lists everything. You have an IDE with plugins, maybe most likely where you can get an overview or find routes just within your IDE. So there's tooling around it that doesn't like, and if you realize the value you get from having a route together with a controller action just in one place, they belong together. There's never like, yeah, there might be very small cases where
Sabatino Masala (35:31)
That's true.
Yeah.
Brent (35:47)
a one single controller action has multiple routes, but by definition you cannot have one route that goes to multiple controller actions. So they always belong together. So just keep them together. You every time I made a controller in Laravel, they're like, okay, first step, create the class. Okay, now next step, I need to go to my routes file. need to edit it. I need to find the right spot where it belongs.
Sabatino Masala (35:55)
No, exactly.
Yeah, exactly. It may be in a group, it may be in it has to in the right middle bear.
Brent (36:19)
Yeah, anyway, that's a side note here. But I've written a blog post about it as well, like the case for route attributes. But besides, we were talking about Laravel being able to adopt this syntax. And they might, but it will take them years, because they're now only started to read, well, a year ago. But they started to include attributes. And attributes are pretty easy when you talk about
Sabatino Masala (36:24)
Yeah, yeah.
All right, I'll check that out.
Mm-hmm.
Brent (36:47)
backwards compatibility, they are just additions, right? But property hooks, they are a massive breaking change if you want to like introduce them into your framework in a non-optional way. So yeah, that will be interesting. That will be very interesting.
Sabatino Masala (36:48)
Mm-hmm.
Yeah, I'm very curious to see if they will manage.
Brent (37:04)
in probably over time, but it will take years.
Sabatino Masala (37:06)
Exactly. But maybe on the topic of eloquent, I used like the accessors, if I'm not mistaken, that's called and the mutators. But those things bit me in the ass multiple times with like n plus one queries because you may access something that hasn't been loaded or a relationship. But I do think with the setters or the getters, I should say, you have that same kind of
Brent (37:14)
Mm-hmm.
yeah, yeah.
Yeah.
Sabatino Masala (37:33)
Danger where, for example, you get, I don't know what value you would get, but if there's a calculation behind that value, it could be potentially dangerous to introduce very hard to debug issues.
Brent (37:34)
Definitely, yeah.
Yeah. Yeah.
The same would be true with normal getter. If you would do the same in a getter, then... mean... No, but it's something to look out for. And definitely in area where you're dealing with database queries and stuff like that, those are the places where performance usually goes to die, basically. So, yeah, I mean, I don't think there's language syntax that could really solve those problems.
Sabatino Masala (37:49)
Very true, very true indeed.
Yeah, indeed, indeed.
Brent (38:16)
It's more of a architectural design problem to think about. It's interesting that you mentioned lazy relations within Laravel and eager loading and stuff like that. Because PHP 8.4 also has a new feature called Lazy Objects. And they basically are a way to have these kind of proxies where you, for example, have a user
Sabatino Masala (38:28)
That's eager loading indeed.
Okay.
Brent (38:44)
Or maybe I should use the author and the book example because that's easy because I have it in my head. So you have an author with multiple books. And you load an author from the database. But you don't need its books for now. You don't want to load everything. But when you do want to access those books somewhere later down, this is like lazy loading in Laravel, right? Laravel will just like.
go perform the query for you, even though the property wasn't loaded and will fill that data in the right place and you never notice it. It does so with a lot of magic. And now PHP has lazy objects. And basically it means that you create a placeholder for, for example, that collection of, what was it, books, right? An author has a collection of books. And instead of truly loading the books, you say, want to, I use a lazy object.
which is something with Reflection you created via the Reflection API. And then you set that collection. It's like a fake book collection then. It doesn't have anything in it, but as soon as you try to access it, then it will do the query and then it will do its thing. It could also lead to a lot of performance issues, of course. But when used correctly, and it was specifically designed by Nikolas Grekhas from Symfony.
Sabatino Masala (39:49)
That's what got loaded in memory. Okay.
I can imagine.
Brent (40:05)
I think together with some of the people from Doctrine as well, because those like the ORM style problems are very suited for lazy objects.
Sabatino Masala (40:20)
So I was thinking in my head, like, are there non ORM use cases for lazy objects that would benefit your code base? So for example, I'm thinking like heavy computations or do you have like an example?
Brent (40:32)
Yeah.
Yeah, something like maybe files or parsing big CSVs with nested data, stuff like that is something that comes to mind.
Sabatino Masala (40:45)
Yeah, maybe getting a file or doing a file operation, for example, like a resize of an image, something like that, a resized image property. Yeah, but it's a very interesting thing. I didn't know it wasn't in PHP. It wasn't available in PHP already, actually.
Brent (40:52)
could be.
Yeah, and they had to rely on a lot of like black magic even to to get it working. No, because it already worked like for for a decade or something doctrine as this this proxy manager package. But it relies on so much magic that it's like, it's irresponsible. So but yeah,
Sabatino Masala (41:03)
Okay. Yeah.
Mm-hmm.
But this is like a feature that other languages usually have like C, I can imagine C has something like lazy or Objective-C or Swift, things like that have. I think even JavaScript has a thing called proxy or lazy object. This is a beautiful example where PHP is actively implementing new features. It's actually very interesting. And to us today, it seems like this feature was already there. It should have already been there maybe.
Brent (41:21)
Hmm.
I have no idea.
Mm-hmm.
Yeah. Yeah.
Sabatino Masala (41:47)
But the fact that it's there now and to be used, it's just amazing.
Brent (41:52)
It is, it is. Yeah. So yeah, that's lazy objects or proxies, whatever you want to call it. So let me tell you.
Sabatino Masala (41:59)
All right, so far we have like the omission of the brackets, we have the property hooks and we have the lazy objects. Yes, correct.
Brent (42:09)
lazy objects. Yeah. Let me tell you something else here. So back to our property hooks example, we have, you know, you have now public properties and we just embrace the public properties API, you know. By the way, property hooks, they also work with protected and private properties, but like the beautiful thing is that you can have public properties that are just
Sabatino Masala (42:30)
Okay.
Brent (42:38)
being used directly and you have the hooks if you need them. But there's one problem with that because now your properties are public. Even the properties without hooks, they are public. You might not always want your properties to be publicly writable. mean, usually it's the class internally that determines how
Sabatino Masala (42:48)
Yeah, I know where you're going with this, I think.
Exactly.
Brent (43:07)
like what goes into a property and you can add property hooks if you need to like add extra logic to it but for the majority of properties you actually you just want to say hey don't write to it to this property from the outside i mean just read it please just directly from the property because that's much nicer than having to rely on getters but like don't ever write to a
Sabatino Masala (43:24)
Mm-hmm.
Brent (43:37)
public property on a class. And so there was this issue now with property hooks, very, okay, yeah, okay, public properties, that's all nice, but yeah, now we also open the door to, well, little less good things. And so they added another feature, and that's asymmetric visibility. And asymmetric visibility, it is what the name says, but it's like,
Sabatino Masala (43:57)
Okay?
Brent (44:04)
it might be complex, but a property has visibility, public, private, And making that asymmetric means that you can set different visibility levels depending on the operation and like the write or the read operation. So in essence, you can have a property that's publicly readable, a public getter, but it's not a getter, and then have it only being privately settable, like.
Sabatino Masala (44:08)
Mm-hmm.
Mm-hmm.
Okay.
Brent (44:34)
private set, right? And that's really cool because now together with property hooks, now we can like truly embrace properties as part of the public API because you have the certainty you can, if you want to, you have the certainty to that properties cannot be changed from the outside, but they are still available there to read and you don't need extra getters and setters, but let's dismiss setters for now. You don't need extra getters.
So you can just have the property and you don't have to worry about unforeseen side effects.
Sabatino Masala (45:09)
So to put this into an example, have a person, for example, who has an age. So who has an age and you can read its age, but you cannot set its age because the person needs to have a birthday before its age increases. And only on the birthday, the age would increase. So exactly. So the class would have like a private has birthday today. You have a cron job running, et cetera. And that's
Brent (45:12)
Mm-hmm.
Yeah, exactly.
Yeah, and then the class would handle that internally.
like that.
Sabatino Masala (45:39)
will trigger the incrementation of its age, but you cannot increment the age from the outside. So that's very interesting. So in your property hooks, you could have like private sets and then public is default, I assume.
Brent (45:44)
second.
Yes.
Yes, yeah, yeah. Well, the syntax is a little bit weird. Well, weird, yeah. have, when you define a property before, it's public, book, book, for example, like public and then the type book and then dollar book, the variable name. Now you have public, private set, book, book. So there's a, like that's the asymmetric part. The thing is like, because you can also have a protected set by the way, so public protected set or
Sabatino Masala (45:57)
Okay.
Okay? Okay.
Okay.
Brent (46:23)
protected and then private set. The thing is that the read context must always be more lenient than the right context. So you cannot have a property that's publicly writable, but only privately readable. That doesn't exist. Yeah, exactly. So the first visibility keyword is like the standard, like everything for everything.
Sabatino Masala (46:32)
Yeah.
Yeah, That doesn't make sense either, indeed.
Brent (46:50)
unless you add a visibility for the set context specifically and then you add a second visibility. And because public private sets specifically are probably a very common use case, they also made it so that if you just have private set without the public, then PHP will assume that it's a public property with a private set visibility. So yeah, if you see it, it's a bit weird, honestly.
Sabatino Masala (46:56)
Okay.
Okay, so...
Brent (47:20)
but you need to get used to it, right?
Sabatino Masala (47:21)
Yeah, I'm trying to picture it in my head. Yeah, but it kind of makes sense, I guess, where so public private sets where if you say private set that it implicitly means like public get, I think it kind of makes sense, but I'd have to see an example for it to click.
Brent (47:36)
Yeah. There's also no, there's no public get. It's just public. Right. So it's, it.
Sabatino Masala (47:45)
Okay, so you could say private get private set book book. Is that a possibility? That's just private. Okay, so if both the getter and the setter are equally, so not are symmetrical, so to say you don't have to write it in full. Okay.
Brent (47:54)
No, then it's just private. Yeah.
You don't have to, it's possible by the way. I believe it's allowed, but I don't think, I think QA tools will like, then simplify it. So even though the syntax is a bit weird and it is a bit weird, I mean, we need to get used to it, but we also had to get used to other things in the past. So we'll get used to it. It is really cool. And it is actually, if you...
Sabatino Masala (48:12)
Yeah, they will freak out. Yeah, indeed.
Brent (48:34)
There is some overlap with read-only properties in classes here. And that's kind of unfortunate because read-only basically means only write once to this property. But in reality, what people actually most often wanted to do is not only write once, but just make sure that people from the outside cannot alter my property. And so we used read-only for that because there was no other alternative to it.
Sabatino Masala (48:58)
Mm-hmm.
Brent (49:05)
we used to use read-only properties for this because there was no alternative for it. But now we have our dedicated syntax for it. And actually, means that read-only, it doesn't really become obsolete. But in reality, it will pretty much become obsolete because like,
In most cases, what we were using read-only for was to make sure that we could have public properties without having to worry about people changing it from the outside. The downside of read-only properties is that even the class itself couldn't change it internally anymore. And that's now possible with private set. What I find unfortunate is just like read-only was introduced in PHP 7.1, I think.
You know, it's already now becoming a little bit obsolete. And this highlights for me,
PHP internals is just a group of people you know, everyone with their own agenda and there isn't really like a clear direction. I really hope that the foundation will improve the situation over time. like Nikita, when he still worked at PHP, and I really liked Read-Only by the way, for the record, was a great RFC and we really needed it back then. Read-Only was added and now a couple of years later we get a new feature that kind of makes like...
Sabatino Masala (50:14)
Mm-hmm.
Brent (50:31)
read-only obsolete, but not really, but in practice it will. So we're only a couple minor versions later and PHP already has become like a lot of code could in theory be refactored to be better. And this just highlights to me like some of the problems with how PHP is developed. I don't have a solution for that, but yeah.
Sabatino Masala (50:57)
It's a very tough problem indeed, but it also highlights the discussion we had earlier. Like, I'm a very slow mover and sometimes you feel like the fatigue of jumping on the next big release as an early adopter. then down the line, you're like, wow, but now they have this other great feature and you have to refactor everything you did two years ago. And if you're a big corporation, obviously you have the resources to do that. But if you have a startup.
Brent (51:07)
Hmm. Yeah.
Sabatino Masala (51:25)
It's going to be very challenging to keep up to date. And that's why I am actually a very slow mover. My multi-tenant food ordering app is still on PHP 8.2, if I'm not mistaken. So I'm always like one or two releases behind. I can, in Dutch we say, you can look the cat out of the tree. It's a proverb. But now in PHP 8.4, you have this beautiful feature with the asymmetric visibility.
That is something I would potentially integrate in my project. Not today, maybe not next year, but in a year and a half, maybe I might consider implementing it. So yeah.
Brent (52:08)
It's like the language evolving and I like this feature. I have use cases for it, but I just wish it was added before read-only and that we didn't need read-only anymore. so yeah, mean, yeah, was asymmetric visibility was already proposed for 8.3 and then it was denied. And that's very interesting. The PHP foundation, they wrote a little blog post about it, like comparing the results.
Sabatino Masala (52:18)
Exactly.
Okay.
Brent (52:36)
And that's another rabbit hole, but like the people who voted no last year just didn't vote anymore this year. And it makes you wonder like, yeah.
Sabatino Masala (52:43)
Okay, yeah, I think I saw something around that indeed. I have the RFC open here, the asymmetric visibility one, and it's indeed proposed in 2022 already. It's been proposed back then. And like you said, the syntax is a bit special. I thought in my head it was easier to get used to, but if you see it like public private set string bar, that is a bit special indeed.
Brent (52:49)
Mm-mm.
Yeah. Yeah.
Yeah, it is.
Yeah. Yeah, and keep in mind, you can combine promoted properties with asymmetric visibility with property hooks. Now try to get a mental image of that.
Sabatino Masala (53:17)
Okay.
So could have a user in its constructor, you have a first name and a last name and it has only a private setter. So you would say public private set string first name or without the public private set string last name. That's correct.
Brent (53:31)
or without the public.
Right, and then you could still add hooks for those properties. Just imagine the inside of the constructor. Yeah. Yeah, so I don't know how I feel about that. It's not because it's possible that it should be done, but yeah, that's something to consider. And we'll see what time brings, of course. But.
Sabatino Masala (53:40)
inside the constructor as well. wow. That's indeed wow.
Yeah.
Indeed, indeed.
Brent (54:02)
But I like the feature. again, it's one of the things that will make it like require quite a lot of refactoring work with them within Tempest. But I'm lucky because like no one's using it. Well, more and more people are using it. I don't know why, because it's...
Sabatino Masala (54:13)
Yeah, I saw you have like over a thousand stars on GitHub. That's impressive.
Brent (54:17)
Yeah, yeah. And there's a small community around it. I mean, I'm proud of what the project is turning into, but it's still alpha. mean, we can still break a lot of things. It's still greenfield, right? And that's nice because it means like, okay, let's bump to 804 and let's change the whole, like 90 % of all interfaces doesn't really matter. Well, we'll go through the struggles of updating the one or two projects that are written in Tempest. But...
Sabatino Masala (54:44)
Yeah
Brent (54:46)
Yeah, it's just nice. I just noticed by the way on my blog there I have a typo there. Anyway, it doesn't matter. I'm scrolling through like the list on my blog here to know what we're talking about. So, asymmetric visibility property hooks, new without like the brackets, we had lazy objects. There's also an array find function. I just want to mention it. It's pretty cool. It's one of the things that you say, okay, didn't we have that before? No, we didn't have an array find function.
Sabatino Masala (54:55)
Okay.
We never had an array find.
Brent (55:16)
No, but the thing with ArrayFind is that it's the same as what Laravel has with CollectionFirst. So it matches the... like you give it a closure and the first match for which the closure returns true will be returned and that's it. So it doesn't like find multiple items if you want to do that you need ArrayFilter. yeah.
Sabatino Masala (55:24)
Okay.
yeah, it was array filter and indeed instead of array find. Yeah, an array filter gives you back an array obviously and then you have to take the first index if it was found. Okay.
Brent (55:45)
Yeah, exactly. So Array Find is basically Array Filter, but it returns as soon as it finds a match.
Sabatino Masala (55:52)
I think saw a snippet on X last night. think Povellas tweeted it. It looked so familiar that I was thinking like, didn't we have this? But it's indeed array filter minus the selection of the first index.
Brent (56:02)
Yeah, you're like... huh?
Mm-hmm.
Yeah, yeah, but more performant, of course, because with array filter, you would have to iterate over all items. And now it's already fine. It's just early return as soon as you find a, yeah, yeah. We also have a deprecation. Implicit nullable types are deprecated. And I don't know if you know what these are, but let's say you have a function where you have a typed parameter. I have my example here, save.
Sabatino Masala (56:14)
Okay.
Okay, yeah, it breaks out of the loop, so to say. Okay, very interesting.
Brent (56:41)
a function called save and then it takes a parameter of book, right? You could assign a default value of null to that parameter without marking the type as nullable. And just having that default value as null means the type would become nullable automatically behind the scenes and that's deprecated.
Sabatino Masala (56:49)
Yeah.
Okay. All right. So now you would have to say like the book is optional.
Brent (57:06)
Yeah, you would like make book either at the question mark or union type with no. Yeah,
Sabatino Masala (57:09)
The question mark indeed.
Brent (57:13)
So yeah, but this was one of these weird PHP things. And it was added for some kind of reason. I can't remember it. Someone told me, and then I forgot about it. So...
But I think it's a good thing because it's just very weird to...
Sabatino Masala (57:28)
And I'm looking at the syntax here. It's also a bit special that you have to say question mark type instead of type question mark in PHP because other languages have like, for example, Swift, you have like the question mark, but they also have like the things like generics, et cetera. But the question mark comes after the type.
Brent (57:35)
Yeah. Yeah, I know. Yeah. Yeah. Yeah.
Yeah, I've never really like PHP is my, not my only language, but the only language I really use. So I'm not really used to that. This makes sense to me, but I know there are many other languages that turn the question mark around, but yeah.
Sabatino Masala (57:59)
Yeah, it's like in the Spanish language where a question starts with a question mark as well. So it kind of makes sense because you see like book with the question mark before you immediately see like it's nullable. And in other languages, you turn you flip it around, you see like book, but it could be nullable. Yeah, but it's a it's interesting. It's a small change. So it's deprecated right now. Right. So in PHP nine. Okay. All right. So that gives us a lot of time to adapt to that.
Brent (58:10)
Mm.
It's deprecated. It will be removed in PHP 9.
Yeah. There's new HTML5 support, which took them a long time. It's really nice because we had like this, what was it called? The Mastermind HTML5 package, which was used almost everywhere. And it was an HTML5 parser written in PHP. And this is an HTML5 parser in Rust, I think, that's being wrapped within PHP Core.
Sabatino Masala (58:31)
Alright, finally!
Yeah.
Okay.
Brent (58:56)
Something like that. So it's more performant. The only thing is, and I learned this because I updated Tempest. So Tempest has a view engine, and it's kind of different from Blade or Twig in that it actually parses the DOM and then starts applying changes to it. So I needed a DOM parser, basically. And so I first used PHP's built-in
Don't parser, of course it didn't work because it's modern HTML and yeah, it didn't work. So then I used HTML5 parser from masterminds and now I could switch to the new PHP implementation. And it's really nice except for there are apparently there were some not like the mastermind implementation used a spec that was a couple of years old and didn't update afterwards.
Sabatino Masala (59:49)
Okay.
Brent (59:51)
And apparently, like, I don't know if you've heard of this, but there are no self-closing texts in HTML. Like, div...
Sabatino Masala (59:57)
There are no like VR.
Brent (1:00:00)
Yeah, there are some exceptions. Actually, I don't know about this for sure. No, I think you need to write just br without a slash. I think that's the right approach. Yeah.
Sabatino Masala (1:00:01)
Okay.
And like image? Okay. okay. Okay. wow. Mind blown. Yeah, they don't care.
Brent (1:00:12)
Yeah, yeah, yeah. Most browsers, they don't really care because no browser is 100 % spec compliant. But I, well, I mean, in Tempus, the view engine, it has view components where you often have self-closing tags, basically, like custom created self-closing tags.
Sabatino Masala (1:00:31)
Mm-hmm.
Brent (1:00:35)
And I just assumed, I mean, it always worked. I just assumed it was part of the spec, but apparently it wasn't. So suddenly code started to break everywhere. I was like, huh, what's happening here? And I thought it was a bug with PHP, but no, it was just, it's just, yeah, part of the spec. I had to, my fix in Tempest, by the way, because this is in the context of a view engine, I can do whatever I want, right? So I can, can.
Sabatino Masala (1:00:52)
Yeah, nice.
Brent (1:01:03)
just like PHP does with promoted properties and move them around before actually compiling the code, I could do the same. So I just take the string of text, the HTML, and I will look for self-closing tags before I parse the DOM. I will look for self-closing tags and then replace them with a non-self-closed. And then I parse the DOM and then everything works. So yeah.
Sabatino Masala (1:01:21)
Okay.
and then you replace them. Yeah, that's actually really clever. Clever. Yeah, nice. Yeah, I had I had a funny discussion with a friend yesterday, where, you know, the badges like HTML five or HTML compliant CSS compliant. In my entire professional career, I don't think I've written HTML compliant W three HTML compliant code. And when I was in high school, not in the university college, I mean,
Brent (1:01:45)
Yeah.
Sabatino Masala (1:01:53)
That was one of the things that would mean you would fail the class if you would ever submit something with invalid W3C compliant HTML, you would immediately fail the class. they really hammered the fact that it needed to be compliant. But in my professional career, never, ever, ever.
Brent (1:02:05)
Yeah. Yeah.
Wow, wow. mean, that's so old fashioned because I mean, I didn't have the problem in college. We still had to write the code on paper. No, I think I'm dating the school. know you went to Ghent, I guess. yeah, of course. Yeah, that's like the Silicon Valley of...
Sabatino Masala (1:02:22)
nice. Nice. Yeah. You're maybe dating yourself here, yeah. I went to Kortrijk. I went to Kortrijk. Yeah.
Yeah, yeah, of Belgium. Yeah, yeah, yeah.
Brent (1:02:38)
of Belgium when it comes to IG. Yeah, no, I went to Leuven and it's maybe they are still writing on paper. don't know. It was, I'm not entirely against it, by the way. It really makes you get a feeling. Yeah. So it is interesting, but like, yeah.
Sabatino Masala (1:02:44)
Okay.
Yeah.
No, it makes you think.
Like I used Sublime Text for the longest time because it didn't have like all like nowadays I use PHP Storm. I love it. It's super easy to get like the magical features, etc. But I used Sublime Text for the like the first five years of my career because I really wanted to get the feel for the languages I was typing in and get it from my head instead of relying on Intelligent, Autocomplete, etc. And I do think that makes you a better programmer because you know...
Brent (1:03:02)
Mm-hmm.
Yeah.
Right. Yeah.
Yeah.
Sabatino Masala (1:03:29)
the longest methods, et cetera. And it really makes you think in a different way because nowadays it's easy. turn on JetBrains, autocomplete or the AI features or even GitHub Copilot. You don't even write a couple of letters and you get like an auto suggestion, you press tab and you really don't think about the code as much, but...
Brent (1:03:33)
Mm-hmm.
Hmm. Yeah. Yeah.
Yeah.
Hmm.
Sabatino Masala (1:03:54)
So I do understand where you're coming from when you say like, it's not a bad idea to write code on paper. It really makes you think differently about certain problems.
Brent (1:04:07)
Yeah, I think actually that's it's a very interesting topic. We need to dive into a bit deeper in another episode. I have some more thoughts about it, but I'll continue with PHP 804. So there were some changes to the JIT as well, but nothing noticeable. And like the JIT, I don't know about the JIT. There are some cases where it really improves performance, but not like, like for web applications. I benchmarked it again. No, no, no, no.
Sabatino Masala (1:04:10)
Yeah, definitely. Definitely, indeed.
Definitely.
Is it enabled by default, Jit? Okay.
Brent (1:04:37)
No, and it doesn't really make a difference. It might even, like in some cases it slows down for web apps. So yeah, the JIT. But there are some, I heard an example recently where they wrote like a CSS parser in PHP, but I think this was an internal company thing and they enabled the JIT and it was 10 times faster. But this is like, those are the things where the JIT is really...
Sabatino Masala (1:04:40)
Okay.
Wow.
Brent (1:05:04)
made for, like it's useful because you're nested loops basically and that's what a JIT can really optimize. But it doesn't really happen all that much in web applications. So.
Sabatino Masala (1:05:17)
Yeah, I don't I really don't know a lot about the JIT, but I think it's an interesting topic. I dive into that a bit more and even do like some benchmarking with my own application because we do a lot of parsing as well. So it might have a positive impact on the performance there.
Brent (1:05:24)
Mmm.
Yeah, that could be...
Yeah, yeah, by the way, the JIT just in time compiler. it basically means that this is a part of PHP that will look at PHP as it's executing code. And once it determines that, okay, here's a snippet of code that is like looped a lot of times, a hot part of the code, it can take that code and it will try to optimize it and convert it to assembly language basically so that
Sabatino Masala (1:05:48)
Mm-hmm.
Okay.
Brent (1:06:06)
a huge part of overhead is skipped for that small piece of code and it's doing all of that on the fly. But there is some overheads doing the checks and then generating the code. you know, and for web apps, doesn't like, I've done quite a few benchmarks over the years, never really seems to make a difference. yeah.
Sabatino Masala (1:06:18)
Yeah, I can imagine.
Okay, all right. But nevertheless, a cool addition.
Brent (1:06:37)
Now, what else? What else? There is a new object API for BC math. And this is actually pretty important. It was like a small feature that I overlooked when I first wrote my 8.4 change log blog post. So BC math is this built in library where you can like work with big numbers, right? And you represent numbers as strings and then you don't have to deal with floating point errors and stuff like that. Now,
Sabatino Masala (1:07:02)
Okay.
Brent (1:07:05)
This was a collection of functions, like for example, BCMath add or multiply or divide some BCMath? No. Basic calculator. Yeah.
Sabatino Masala (1:07:11)
Do you know what it stands for by the way? BC? Just out of curiosity.
basic calculator. All right. Yeah, I just know it's always a reflex when I I install PHP on a new server like XBC math. Okay. But you never give it second thought because it's just Yeah.
Brent (1:07:23)
Yeah.
Yeah, exactly. But it has like these functions, BC add, BC seal, comparative, mods, floor, blah, blah. Right? Basic calculating, calculator, mathematics. But it's very precise because it's working with strings and it knows how to deal with that. more, it's approaching math more from like a human point of view instead of...
Sabatino Masala (1:07:44)
Yeah.
Brent (1:07:59)
a computer point of view where you run into floating point errors and stuff like that. So it used to be a collection of functions and now they've made it into an object oriented API and you can just do number one equals new number. So number, it lives in the BC math namespace. And you pass it a string of a number. And then this is pretty cool. You can actually then, as soon as you have these variables, which are objects, you can use normal arithmetic operators on them. So you can just...
Sabatino Masala (1:08:00)
Okay, the floating point indeed.
Okay.
Okay.
Brent (1:08:28)
number one plus number two. So it's operator overloading kind of for this specific thing managed by PHP itself. Yeah, and that's really cool. So whenever you need to deal with money, for example, is a pretty common use case where you don't want rounding errors and stuff like that. You could now use the object oriented API, which is much nicer.
Sabatino Masala (1:08:37)
That's interesting.
But I do think money is a special case. I think you have like the package money. It's a PHP package because it's very you have like cents. You have to deal with cents. And if you pay, for example, you're going out with three friends and the bill is $10 or 10 euros and you split it equally. Someone has to pay 3.34 and all the others have to pay 3.33. So I do think
Brent (1:08:57)
Yeah,
Sabatino Masala (1:09:20)
Money is a bit of a special use case, are those cases covered in BC Math?
Brent (1:09:25)
Well, BCMath is just about doing the arithmetic operations on it. So anything like more context would need to be built on top of it. But I'm fairly certain that the money package you're talking about is using BCMath underneath to also like to deal with the calculations and then adds a layer on top of it.
Sabatino Masala (1:09:29)
Okay.
Okay, all right. Yeah. So in theory, you don't have to deal with money as cents anymore, because that's a popular thing. Instead of saving one euro in the database, you save like 100 cents.
Brent (1:09:51)
Yeah, yeah, true. Yeah, but the problem there is that if you, if you save it in a database, then you would need to save it as a string in a database as well. Because all right, the database would also have rounding issues, right? If you would save it as a float. So if you don't want to do like arithmetic operations within the database for queries, for example,
Sabatino Masala (1:10:07)
Okay.
Yeah, definitely. Indeed.
Mm-hmm.
Brent (1:10:20)
more difficult, mean pros and cons.
Sabatino Masala (1:10:23)
So there's no cost function in my SQL for example, you cannot say give me all the orders where the value is greater than or equals 100 for example. That would not work anymore if you save it as a string. Okay. Okay.
Brent (1:10:35)
If you store them as strings, no. yeah. There's a deprecated attribute now. You can use it instead of like the at deprecated doc block and kind of works the same. But it's now built into PHP, basically. And then there were some changes to functions all over the place. I'm not gonna, like, doesn't make sense to discuss them here because...
Sabatino Masala (1:10:49)
Okay.
That's cool.
Brent (1:11:04)
It's a long list, yeah, PHP 804. mean, super cool release. Like the biggest things, of course, are like the changes to properties with property hooks and asymmetric visibility. For me, still, the brackets are the the biggest, coolest thing. So yeah.
Sabatino Masala (1:11:22)
Yeah, obviously. Yeah, indeed. Nobody said it's very interesting. Thank you for the overview. I was really surprised by the asymmetric property hooks. I think that's that's a great addition. The property hooks indeed, but the asymmetric visibility. Yeah, I'm I'm already. Yeah, it's not confusing at all. Nobody's very interesting. I definitely give it a go.
Brent (1:11:29)
Hmm.
Yeah, proper t-hooks.
visibility. Yeah. Yeah, yeah, yeah, yeah. Yeah, it's not confusing at all.
Sabatino Masala (1:11:50)
with a new project. But as I said before, my multi-tand food ordering app will stay on 8.2 for the foreseeable future until it, do you know by heart when it goes, when it's not managed anymore, when it's not.
Brent (1:11:50)
Yeah.
Yeah. Yeah.
Sabatino Masala (1:12:10)
They changed the table, the end of life table is gone.
Brent (1:12:14)
Yeah, no, it's not gone. Hang on. But it's I don't know, it doesn't. There's a Google problem and no one knows how to fix it. And now there's like a like an SEO optimized.
Sabatino Masala (1:12:22)
Okay.
Brent (1:12:33)
blog post instead on top of Google and it's really annoying. Let's see here. PHP 8.2 is, yeah, in January 2025 it ends like active support and then it has two more years of security fixes.
Sabatino Masala (1:12:45)
Okay, so I think I might upgrade it within a year. I might upgrade to, I may be jumping to 8.4 directly. I may skip 8.3 as it's a pretty minor release. So yeah, nice. But it's a very nice release.
Brent (1:12:50)
Yeah.
Yeah. Yeah.
It is. I'm really excited about it. Lots of work to be done still for me as well with Tempest, but yeah, it's a big one. I'm happy with it.
Sabatino Masala (1:13:15)
Yeah. do you use, what's your upgrade strategy for projects? If you still do projects, I don't know if you still do projects, but what's your typical upgrade strategy?
Brent (1:13:24)
Rector. I don't do many projects anymore. The biggest projects I work on is Tempest. And we kind of apply the same strategy on Tempest as well. this combination of Rector and PHP CS fixers to automate whatever is possible. But in case of property hooks and asymmetric visibility, it's not something like a simple syntax change. It's like conceptually changing
Sabatino Masala (1:13:30)
Okay. Okay, okay.
Brent (1:13:54)
your interfaces and implementations and that's not something that's automated. So it's, yeah, it's manual work.
Sabatino Masala (1:14:03)
Yeah, indeed, indeed. All right. But I think we can wrap it up here. It's been already over an hour, an hour and 15 minutes. So it's been a great talk, Brent. Thank you very much for your time.
Brent (1:14:08)
Bye bye!
No spam, no sharing to third party. Only you and me.