تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Problem: Null Auth User0:00

I bet one thing you'll find yourself doing all the time within your views is checking to see if the User is signed in. So you might do something like if(auth()->check()), if they are signed in, and the User is subscribed, then do something, right? Like display a download button, okay? We'll just simulate that with this. And yeah, I bet you're going to end up doing this over and over, where you want to ask your User object something. Are you subscribed? Did you purchase this?

Are you subscribed? Did you purchase this? Do you have followers? Any of those things. But in order to call that method, well, you have to make sure that you have a valid User object, right? Because if auth user returns null, then for all guests, well, you'll end up trying to do something like this, and of course an error will be thrown. Can't call isSubscribed on null. So yeah, as a result, you end up doing this over and over.

Can't call isSubscribed on null. So yeah, as a result, you end up doing this over and over. Check if the User is signed in, and then call the method. And then you'll do it somewhere else, and then somewhere else. But let's try this out. So I'm going to go to AppServiceProvider, and I'm going to say auth()->loginUsingId(). I'm just going to simulate a signed in User, since we don't have an actual app here. All right, so let's go to nulluser.dev, and it fails. No method called isSubscribed, okay? Let's go to the User object down here, isSubscribed, and once again, we don't have an app, so I

No method called isSubscribed, okay? Let's go to the user object down here, isSubscribed, and once again, we don't have an app, so I will stub it out. But anyways, if we refresh, now we get a download button. But yeah, if we come back and we log the user out, auth logout, make sure we only have a guest. Give it a refresh, and we get nothing, which means everything is working. And further, we could even say, else, please sign in to download videos. And yeah, that'll work, so we will see that. But it would be nice if I didn't have to do this in every single view.

Sharing Auth Data in Views2:16

Now I want that to be available to all views, and I only do that with a couple things. You don't want to go crazy sharing dozens of variables with every view. But one or two big ones I think is okay. So we can do that like this. You can say view->share('signedIn', auth::check()); Okay, so now every single view will have access to a signedIn variable that just delegates to auth::check() like before. So if I come back and give that a refresh, everything still works. But yeah, this reads a little bit better to me in my views. Next, kind of going in line with that, auth::user(), once again, no problem at all.

But yeah, this reads a little bit better to me in my views. Next, kind of going in line with that, authUser, once again, no problem at all. But I also like to change that to user, or some people call it authed, or some people call it authUser. You know what, anything you want. We'll stick with user. So once again, that's not going to work. We log the user back in, and there is no variable. Okay, well let's do that one as well. User will be authUser.

Okay, well let's do that one as well. User will be auth()->user(). If we come back, give it a refresh. Now we have what we had before, but once again, this is a little easier to write. And now in any view, if you just want to check if your user can do something, yeah, this is a nice way to go about it, I think. But we still have this problem where we're doubling up, where we always have to say, well, if you're signed in, and then if I can call this method on a User object, then proceed. Maybe it would be cool if you could just do this, and it will work regardless of whether you have an authenticated user or a guest.

Maybe it would be cool if you could just do this, and it will work regardless of whether you have an authenticated User or a guest. So right now, if I give this a refresh, it's going to work, right? And that's because you are signed in. We did share a User object, so we're good to go. But if the User is signed out, well, User, that's going to evaluate to null, right? And we're right back in that problem that we had before, where we are trying to call an isSubscribed method on null. So here's what you might consider doing. You could say, if we come back to our ServiceProvider, and by the way, if you don't like

Fallback User Instance4:10

So here's what you might consider doing. You could say, if we come back to our ServiceProvider, and by the way, if you don't like this here, you could even create a ViewServiceProvider where you have any of your bound variables or your shared variables. But anyways, what you could do is say, make the $user variable equal to the authenticated user, or if that evaluates to null, then we could just new up a User from scratch. Okay, so now if you're signed in, we get the authenticated user, and if you are a guest, we just get a new instance of User that will satisfy the interface, so we can call these methods. And in real life, things like this would actually do some real checking.

methods. And in real life, things like this would actually do some real checking. It would check to see even if a column on the row is set to one or zero or something like that. So I'm just going to simulate that by saying return $this->exists. That's just going to determine if the User object has been persisted. Yeah, just temporary. In real life, you would do actual logic. Anyways, if I give this a refresh, now, think about it, I no longer need to check if the User is signed in.

Implementing NullUser Pattern5:37

Now, what about this nullUser? Here, we just have, it's not really a nullUser. It's just a brand new instance of User, and we can trigger any of the methods or properties here. But if you want to take it a step further, yeah, you could create a nullUser here. This is a common design pattern. So namespace App; class NullUser, and what I'm going to do here is have it extend User. You don't have to do this, but it'll just make it easier so you don't have to duplicate a bunch of things. But just note, yeah, many people would say remove that, and then for any of the methods

a bunch of things. But just note, yeah, many people would say remove that, and then for any of the methods that you want to duplicate, so to speak, maybe you have an interface here or something, you would have to do that. So here would return null and things like that. So you're basically satisfying an interface while not actually doing anything at all. And I think at first, this rubs people a bit wrong because they think it's kind of disingenuous where you're asking if the user is subscribed, but we don't have a user. So it's kind of misleading. But actually, I'm not so sure it is because if you think about it, we have a user object.

So it's kind of misleading. But actually, I'm not so sure it is because if you think about it, we have a User object. We're not being specific that it is a subscribed User or a signed in User. In this case, it's a guest User, and that's fine. Is the guest User subscribed? No, they're not. So we don't display a download button. I think there's no problem there. And now null User can be responsible for any of the behavior or lack of that it needs to.

And now null User can be responsible for any of the behavior or lack of that it needs to. So yeah, you can do this or you can have it extend User, and that way you inherit the full API on User. And then if you need to override anything, you could declare it here. So for example, maybe you just want to set the name to guest. Now up here, you could say welcome user name. And if we come back, we will get our signed in User. But if you are logged out, then we will get guest. And we don't actually.

But if you are logged out, then we will get guest. And we don't actually. What's going on? No User. Oh, you know what? We forgot to change this to null User. OK. Anyways, now we'll get guest and you can see how this works. But generally, your null User, its entire reason for existing is to fulfill an interface while actually not doing anything at all.

Using GuestUser Class7:44

But generally, your null User, its entire reason for existing is to fulfill an interface while actually not doing anything at all. And that's why we call it null. Any method you would call is subscribed, is going to return null or false or whatever you need it to. Now, on that note, and we'll close with this, if you do find yourself doing things like this where you want to say that your null quote unquote User is a guest and another method is kind of specific for a guest alone, well, maybe the problem is not that you need a null User, but that you need a GuestUser. So you can have different forms of a User, a SubscribedUser, a GuestUser.

a null User, but that you need a GuestUser. So you can have different forms of a User, a subscribed User, a GuestUser. Maybe if you have a super, super premium User who has different rules for what they can access, maybe you actually need to encapsulate that within a class. So if we rename this to GuestUser and update this, now we can come back here. And now this isn't the null User object pattern. This is just creating a dedicated class specifically for a GuestUser. And once again, you may find that this can be useful. So we can return this to false and you get the idea. So give it a shot.

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