Lesson Setup and Goal0:00
Hey there. Welcome back. Let's keep working with php stand. And now let's see how we can implement generics using php stand. Let's jump into the code. Okay, here we have our php stand playground file. On the same state it was on the last lesson, the only change I did was I went to php stand neon and I reverted the lavo back to five. If we run php stand, we should still be green and we are.
Creating a Collection0:23
and I reverted the lavo back to five. If we run php artisan, we should still be green and we are. And now the only other thing that I did was adding this new class Collection, which is what we're going to use for this lesson. So let's write something very basic. Let's say that we have a collection and we're gonna say $invoices is going to be a new Collection and we're going to add an invoice to this collection. So let's say new Invoice, we can save money.
and we're going to add an Invoice to this collection. So let's say new Invoice, we can save money from $major a hundred dollars and this is going to be for Matteas. Whoops, right here. There we go. Let's add a second Invoice. And this one is going to be $300 and this one's going to be for Jeffrey. Now let's add an operation on those invoices. Let's say invoices.each. We're going to pass an invoice here.
Implementing Each Method1:07
Let's say invoices each. We're going to pass an invoice here and we're just going to echo the recipient. Something like this. Obviously this method does not exist, so let's add it real quick. Each this expect a callable, it doesn't return anything. And then we can do, for each of the items, we're going to pass them back as a parameter. Now if we run php artisan serve, we should see some things.
to pass them back as a perimeter. Now if we run php stand, we should see some things. Let's go ahead and just comment out those other calls just so we have a clean state. Let's rerun this and okay, we see the output. Let's also do php and the line. And there we go, Mateo jre. Now here's the problem. Nothing here stops me from doing something like this. What if I say money from major 500 and if I try to run this, it will fail.
What if I say money from major 500 and if I try to run this, it will fail because we have a type hint right here and there we go. Argument one invoice must be of type Invoice at money given. So in this particular scenario, we are safe because we have a closure and we're type hinting the parameter. However, we're still able to add a money instance to this invoice collection when we shoot it. Ideally, it'll be good to know ahead of time
Adding Generic Template Type2:17
to this invoice collection when we shoot it. Ideally, it'll be good to know ahead of time that this is wrong, this is incorrect. And we can do that using generics with php stand. Let's take a look. Here's what I'm gonna do. I'm gonna go to the class definition and I'm going to start a doc block. I'm going to say template. T and T is just a generic type. It's just a place holder, it's T from type. In some cases you're gonna notice people use something like
It's just a place holder, it's T from type. In some cases you're gonna notice people use something like T value or tt, and we're gonna see some examples on this lesson. So now that I have Template T, I'm telling php stand that this class accepts a generic type. Now I'm gonna go to my constructor and we're gonna say that items is an array of this generic type. We've already talked about this. We could do something like this.
We've already talked about this. We could do something like this. Or in this case we could just do T brackets. And then on add, I am also going to say that this guy right here is an instance of T and I could get rid of this. Let's scroll down. And now we need to tell php stand what the generic type is for this collection. If I were to run php stand on this, it is going to pass. So here's what we can do. We can add another doc block.
Annotating Collection Type3:24
If I were to run php stand on this, it is going to pass. So here's what we can do. We can add another doc block and we can say that this $variable is going to be a collection of invoices like this. Let's try rerunning php stand and now it is failing. So line 108, this would be this line. We are expecting an Invoice and we're passing a money. If we were to do it the other way around, if we were to say they're expecting money and we're passing an Invoice, this is going
to say they're expecting money and we're passing an Invoice, this is going to fail on 1 0 6 and 1 0 7. So now we know ahead of time that this collection expands an Invoice, not any other object. So let's go and do this. Now this looks good for the class itself and for its members, but what about the operations that we do on the class for add?
and for its members, but what about the operations that we do on the class for add? It's pretty simple. We can also add T to doc block and php sent understands that. But what about, for example, this each method where we're passing a callback? What if I were to pass something like money here? Uh, would PHP sent complain? Let's see. Well it's complaining about undefined property, so let's actually get rid of this.
Well it's complaining about undefined property, so let's actually get rid of this and let's just say that I'm gonna do you know major here. So we're expecting a money invoice. Let's see what php stand says. No, it is passing and it shouldn't because we know this is a collection of invoices, not money. So this operation will never give us a money instance. Well maybe could based on invoice, but we want it to give us an invoice.
Typing Callback with Generics4:48
Well maybe could based on invoice, but we want it to give us an invoice. So here's what we can do. Let's go to our method and let's also add a doc block. Now we know this parameter is a callable and we can also type hint those callables so we can say something like this. This is a callable and it takes a T as an argument and it returns void. So T is that generic type. That's this guy right here.
and it takes a T as an argument and it returns void. So T is that generic type. That's this guy right here. And as you might have noticed, T works exactly as you would with any other actual instance within your application. Any other actual class, remember we talked about type three. We also have typed cos and we're gonna take a look at them after generics, but we could also do something like this. We could say this is a callable that returns an invoice. So let's try this out. Let's start with this without generics.
So let's try this out. Let's start with this without generics. So we know this should return an invoice, but it's returning something else. So let's run php artisan. And you can see it is complaining callback of math that each expects callable invoice and we've got closure at money. Instead. If I were to change this for money, the SaaS will now pass.
Instead. If I were to change this for money, the SaaS will now pass. However, it is incorrect because this method returns whatever we gave to the class, the generic T type as an argument to the callback. So instead, we must use the generic type like this. And now if we rerun php stan, you can see it is complaining. It expects a callable invoice and we're giving it a callable money.
It expects a callable invoice and we're giving it a callable money. Now, if instead we were to give it a money instance and let's just comment those lines so it doesn't fail and we were to run this, this would pass. Let's undo all of that. Let's say we want an invoice here. Let's say we expect an invoice here and now we could simply say invoice recipient. If we rerun this, we are back to agree. So what we're doing essentially is we're telling PHP stand
If we rerun this, we are back to agree. So what we're doing essentially is we're telling PHP stand that this collection class takes a generic type as an argument. Just like we can type with angle brackets, we can do the same with classes. So we're telling PHP it accepts the generic type, and then we're using those generic types or that generic type specifically within its methods and its constructor.
or that generic type specifically within its methods and its constructor. And as you've noticed, we use it exactly as we would use, for example, a class or a primitive or just passing T instead of money or invoice. And T is variable. It depends on it's given to the class. Going back to the collection example, another thing we can do is narrow down the generic type a little bit. Of course, collections are very generic, pun intended.
Constraining Generic Types7:17
the generic type a little bit. Of course, collections are very generic, pun intended. So this is not the best use case, but let's take a look at what that means. First, let's run php artisan and make sure we're green. And now here's what I'm gonna do. Let's go back to our template definition. And I'm gonna say T must be an instance of Invoice, right? And this should pass because we're passing an Invoice. But if I were to say this should be an instance of Money,
And this should pass because we're passing an Invoice. But if I were to say this should be an instance of Money, it is now going to fail type Invoice in generic subtype, uh, generic type in phpDocumentor, it's not subtype of template type T of App\Money. Long story short, what we passed is not a subtype of App\Money, which is what we defined on the template. You might not use this all the time, but it comes handy in some situations. Okay, I think that was quite enough. Read this lesson.
but it comes handy in some situations. Okay, I think that was quite enough. Read this lesson. We're second to explore generics in the next lesson and some extras on php stand. But here's my suggestion. Before you go and watch the next episode, take a breath, take a break and play a little bit with php stand. Write a new file, write some code, run php stand on, export the documentation, export functionalities. And then once you've done all of that, go
export the documentation, export functionalities. And then once you've done all of that, go and watch the next episode. As I've mentioned several times, php send is very powerful and it is very robust and it has a lot of functionality. So it's important for you to go through the documentation and just play with it a little bit. Just practice a little bit. As usual, I hope you enjoyed this lesson and I'll see you on the next one.
As usual, I hope you enjoyed this lesson and I'll see you on the next one. Bye.
