در حال بارگذاری ...

Remove Livewire Dependencies0:00

All right, folks, it is now time to rip out actual Livewire from what we have set up here and rebuild our own Livewire framework around it. So let's do that. Here's this Counter component that we have. Let's get rid of this extends Livewire\Component. So it's just a plain class, and we're going to leave this whole class as is. Like I said, we're going to rebuild our own Livewire framework around what we already have. We're going to get rid of the Livewire javascripts and the part where we render the Livewire Counter for the first time, and we're going to replace it with our own code.

Create Livewire Render Helper0:29

We're going to get rid of the Livewire javascripts and the part where we render the Livewire counter for the first time, and we're going to replace it with our own code. So let's use Blade, and we're going to echo out. Let's just do this. We're going to make a Livewire function that we can pass this class into. So this app/Http/Livewire, we'll pass it into their Counter. Okay, just kind of inventing our own API for now, just something that's fairly simple, because actually implementing, getting this to work where you can do caret Livewire::, that's actually pretty difficult. And so we're not just, we're just not going to do it, we're going to keep it simpler than

that's actually pretty difficult. And so we're not just, we're just not going to do it, we're going to keep it simpler than that, and just have this function called Livewire, where we pass in the component class. Alright, now to make this function, I'm going to keep it super simple, I'm just going to add some inline php right in this blade file, and do this function Livewire, it accepts a class, okay, and then presumably, we're going to return a bunch of HTML. So check this out. If we return some HTML from this like <div>, hey, right. Alright, so what do you expect to happen? You expect to load up this page, let's actually change this to <h1>, you expect to load this

Handle Blade HTML Escaping1:25

Alright, so what do you expect to happen? You expect to load up this page, let's actually change this to h1, you expect to load this page and you expect to see a title called, hey, right, refresh, and we don't, we see the actual name of the tags right in there. And if we actually view page source, check this out, why didn't that view page source, view page source, if we look at view page source, we don't have those clean, you know, brackets or carrots, whatever we have < and > layer of HTML has taken the plain string that we've passed in here. And instead of just echoing out the exact HTML directly onto the page, it escaped it, it turned it into something safe for HTML.

And instead of just echoing out the exact HTML directly onto the page, it escaped it, it turned it into something safe for HTML. Now this is a security feature. Because if you had a field where users were storing, you know, input in the database, and you were just echoing out onto the page, they could put their own <script> tag that does something malicious and harm other users that use the apps because their browsers will render it. All right, so Laravel, when you do this, Laravel does its own escaping. So we can actually get around that with this double bang here. So let's check this out.

So we can actually get around that with this double bang here. So let's check this out. We refresh. And now we have an actual h1. And when we load the page, it actually just renders as an actual tag. So that's what we want. We need to do that unescaped echo right there. Alright, so we just hard coded in what we're returning here. We don't want to do that. We want to new up this Counter class and call render to get the HTML to return.

We don't want to do that. We want to new up this Counter class and call render to get the HTML to return. So let's do that. Let's say $component equals new Counter. Now this is kind of cool. I don't know if everybody knows this, but you know, you can actually just new up a variable that is a class name. I don't know, it's just kind of a something you might not do in a normal Laravel app, there's going to be a lot of those types of things that we're doing that aren't in normal Laravel apps, kind of pushing the boundaries of PHP and JavaScript, because we're making

there's going to be a lot of those types of things that we're doing that aren't in normal Laravel apps, kind of pushing the boundaries of PHP and JavaScript, because we're making a framework, we're not just making an app. Alright, so we have this component, it's an instance of our Counter class, and we call component->render(), because render is a public function, and it's going to return the string of HTML. And then it's going to echo it onto the page. So check this out. Okay, that's pretty wonky. There's something like what we want, but then all the Blade is directly on the page.

Render Component via Blade3:32

Okay, that's pretty wonky. There's something like what we want, but then all the Blade is directly on the page. Check this out. The Blade didn't get rendered at all. Yeah, because we didn't do any rendering with Blade we this is the Blade part. And Blade just echoed out this string, we need to render it before we echo it out. And Blade actually makes this super easy. There's a facade in Laravel called Blade, where you can just call render and pass in a string, and it will render it, okay, refresh. And look, there's a big problem, undefined variable count in file, and then it references

a string, and it will render it, okay, refresh. And look, there's a big problem, undefined variable count in file, and then it references the blade file, refresh, here's our big error, undefined variable count. So what's happening here is picture this picture, you're inside a Laravel controller or something and you say return view, and you have a counter view, and this is the file, let's say, and you just try to render it. And you're referencing a variable and it wasn't ever passed in, it doesn't exist. So you're going to get that error. If this were a controller, we would do something like this $count, and then pass in a variable like that.

If this were a controller, we would do something like this count, and then pass in a variable like that. Well, this works the same way we're calling we're saying Blade, hey, render the string, Blade's like, wait a minute, we don't have access to count. So there's a second parameter here, where you can pass in arguments. So if we say count is 1, okay, and now we try to render it, it works, it has count now count is available, and it renders it as 1. Perfect. So that's all well and good, but it's not actually good enough, because what we need to do is instead of hard coding in the properties, or that the, you know, the Blade data, we

Extract Public Properties4:53

So that's all well and good, but it's not actually good enough, because what we need to do is instead of hard coding in the properties, or that the, you know, the Blade data, we need to scrape all of the public properties on this class, this Counter class, and need to pass it as the second argument, so that it has the data to render, right. So let's make our own function, it's going to be called getProperties, pass in the Livewire component. And then inside this function, we'll walk through these properties, and we'll return them in an array. So let's do that getProperties. And this accepts the component instance.

So let's do that getProperties. And this accepts the component instance. Now inside of here, let's take an empty properties, we'll just make this empty properties array, and we'll build it up. And then we'll return properties. Okay, now this will build it up. That's the big question mark right here. How do we take a class and get all the properties, the names and the values because we want it to be a key value array, where the keys are the public property names, and the values are the value, right?

Use Reflection API5:44

to be a key value array, where the keys are the public property names, and the values are the value, right? How do we do that? Well, there's no simple way to do it. It's fairly simple, but it's a little bit deeper. This is we're going to actually have to use php's reflection API. Now I don't know if you've ever used it or not, it's kind of a deeper API, but it's very powerful, it allows you to inspect PHP itself, like take a class and inspect it and find information about it. What's the name of the class?

So I'm just going to write it out, because you know what we're accomplishing here. And then you can fill in the gaps in your brain. We know that we're, you know, taking an empty $properties array, and we're building up a full key value $properties array from this instance. So let's do it. First, let's actually dd new ReflectionClass, okay, and pass in $component. Now this is just in php. And let's just look at what ReflectionClass is. So ReflectionClass when we pass in any PHP, it could be a class or an or an instance like we passed in, and it's going to give you a bunch of information about it, look, we can

So ReflectionClass when we pass in any php, it could be a class or an instance like we passed in, and it's going to give you a bunch of information about it, look, we can access the properties, we can access the methods on it. That's pretty cool. So let's get those properties into an array, let's say $reflectedProperties, okay, $reflectedProperties equals new ReflectionClass. And then we can't just call properties because you see the properties here, but it's not a public property, we can't just access it, we have to call getProperties. And then we can actually dd that $reflectedProperties just like this, okay. And now we have ReflectionProperty count.

And then we can actually dd that reflected properties just like this, okay. And now we have reflection property count. All right. Now let's just say that count was a protected property, it would still be in that list. And we don't actually want that we only want the public properties. So there's a way to filter them that you know, there's basically this getProperties method, it accepts one parameter, and that's a filter. We could do that, let's say ReflectionProperty::IS_PUBLIC. That's just a little bit of extra syntax that php uses to detect and filter out properties that are only public.

That's just a little bit of extra syntax that php uses to detect and filter out properties that are only public. So if this one is protected, and we fresh now we get Yeah, there's zero entries in that array. If we change it to public, and refresh, there we go, we get that reflection property. Perfect. All right. Now this is an array of these reflection property instances, which as you can see, they're kind of like they're like reflection class has a bunch of stuff, you can access stuff about a component or sorry, an instance, reflection property, you can access a bunch of stuff.

of like they're like ReflectionClass has a bunch of stuff, you can access stuff about a component or sorry, an instance, ReflectionProperty, you can access a bunch of stuff about a property. Cool. So let's loop through those for each ReflectionProperty. Okay, and then as we'll just do as property. Great. And now inside here, why is this yelling at us because we didn't save or what, like reflectedProperties? Is this not?

And now this is pretty simple. We can just say properties. And the key is going to be the property name, so we can say getName, and the value is going to be property. Okay, now properties getName, we want this to be property, property getValue. Okay, and when you call getValue, you actually have to pass in the instance that you want to get the value on, which is kind of redundant, but whatever, that's just how it works. All right, now we refresh and it actually works. So you can see yourself, if we dd properties, you can see that we have this perfect plain array of count equals zero.

So you can see yourself, if we dd properties, you can see that we have this perfect plain array of count equals zero. If we added another one called foo equals hey, and then refresh, now we would have count zero foo equals hey. So this is a nice little function. You don't have to understand every little bit inside of it, but it's a nice little black box that takes in an instance and spits out all its public properties in a key value array that we can easily pass into something like Blade render and get our rendered component right there. So that's great.

Reflection API

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟