Need Server-Side Validation0:00
Alright, welcome back, everybody. In the last episode, we left off with a cliffhanger, didn't we? We currently have the situation where a User can insert empty data into our database table, which of course, we don't want to allow. Okay, so the solution is to apply a layer of validation, and I'll show you how to do that in this episode. Alright, so yeah, just to restate the problem. Notice right now, if I leave the body text area blank, I can still submit the form, and if I now switch to TablePlus and give it a refresh, we have an empty row that has just been persisted.
Bypassing Client Validation1:32
it is useful. It provides immediate feedback to the user to help them. But there's nothing preventing the user from simply bypassing this layer of validation. And I'll show you what I mean. If I go to my terminal, yeah, there's nothing preventing me from manually submitting this POST request, and I can use cURL for that. So I can say curl -X, and that declares the request type. In our case, we want a POST request. The URL, let's switch back, see if we can find it. Yeah, it's going to be localhost:8888.
The URL, let's switch back, see if we can find it. Yeah, it's going to be localhost, port 8888. And then the URI is /note/create. Next I will pass -d to provide the data to go along with this POST request. So I can say, alright, well, the body should be nothing. We submit it. And yeah, if I now go back to TablePlus and give it a refresh, yeah, there we go. So you see what I mean? We've now bypassed that client-side or browser layer of validation. Okay, and in fact, if I just do it over and over, yeah, we're right back in that same
Inline Validation Logic2:53
And yeah, right here, let's see, it sounds like before we run our query, we should first confirm that the body meets our criteria. And we'll do it inline to start. Alright, so let's see. I'm going to use the strlen function that php provides. Of course, that stands for string length. And we're going to look at the post body attribute. And if its length is zero, well, then it's blank. And that means our validation should fail, right? Alright, so how do we represent this?
And that means our validation should fail, right? Alright, so how do we represent this? Why don't we start by saying, create a variable called errors, and that'll be an empty array. And then we'll do our validation checks. And if this one fails, we will append to that array like this, errors body equals a body is required. Okay, so now think about it. If our validation fails, or in other words, if the errors array is not empty, should we still run this query to update the database? And of course, the answer is no, we should effectively abort and return to the form,
still run this query to update the database? And of course, the answer is no, we should effectively abort and return to the form, and then notify the user about what they did wrong or what validation error occurred. Okay, so let's see if that's the case. Alright, so we can check if an array is empty or has no members or items by using the empty function. So yeah, if I did something like this, we're saying, alright, if there are no validation errors, then it's safe to proceed. So I can nest that here. Otherwise, we don't run that query, and we require the view.
Showing Validation Errors5:06
Okay, so our validation is, in fact, working. But now the next issue, as we discussed, is that we're not providing any feedback to the user. So they have no clue what the problem is. Okay, let's do this. Let's go into our view. And yeah, right below the text area. So let's do this. Let's say, look at the errors array and see if we have anything for body. And if we do, then we should display that validation message for the user.
Let's say, look at the errors array and see if we have anything for body. And if we do, then we should display that validation message for the user. Like this. errors.body. And then we can close this out. Yeah, and I think that would do the trick. So now if we come back and I submit the form, yeah, it doesn't look too pretty right now. But at least we're providing some level of feedback to the user, which is great. Okay, so now let's make it look a little more attractive by saying, how about make it red?
We have the client side or the browser validation. But then we also have a second server side validation that can't be bypassed. So even if we go through the terminal, like we did earlier, notice body is required. Yeah, there it is. And it doesn't work here either. And just to prove it, if we go back to TablePlus and refresh, yeah, there's no empty record here, which is really good. Okay, but we're still not done. Yes, we are ensuring that you give us something, but what if you give us too much of something like this?
Adding Max Length Rule7:08
All right, so let's give it a shot. And yeah, as expected, we blindly throw all of that junk into our database table, which isn't ideal. So it sounds like we need a way to apply a maximum number of characters that we will allow or a minimum. Like imagine you're creating a registration system and you want to say, well, the password that the User provides should be at least seven characters and at most 255 characters, right? You want to set a minimum and a maximum for the number of characters that are provided. These are all things that validation can handle.
You want to set a minimum and a maximum for the number of characters that are provided. These are all things that validation can handle. All right, let's get to work. I will clear that out, switch back to PHP Storm, and yeah, why don't we do another layer of validation? Let's do this. Let's copy that rule and we will run another check. If the length is greater than some kind of arbitrary threshold you've set for your application, in this case, a thousand might be too little. You know, it just sort of depends on what these notes are.
you can imagine situations where for any form input that the user fills out, there could be multiple validation violations that you need to report like, well, you did this wrong, but you also did that wrong. So if you want to allow for that, we might need to structure things a little bit differently. But for now, let's just keep it simple. Okay. So anyways, we submit the form and sure enough, a body is required. Now we require something, but I will add so many characters that will hopefully take us over the 1000 character maximum. We submit it and the body cannot be more than 1000 characters, which is great.
Preserving Form Input9:30
And maybe I would have preferred to fix the mistake rather than starting from scratch. Very likely that's the case. Okay. So how do we how do we do this? Well, let's come back and let's go to our view and maybe right here as the value. Of course, we can just add gibberish here and that will be included. So maybe we could just say, well, if we have anything in the post message body for this, then we should echo it out. So maybe something like this echo $post->body. But yeah, it's not enough to do this.
So maybe something like this echo post body. But yeah, it's not enough to do this. This might be your first thought. But notice if we give this a refresh. Yeah, we get a warning, undefined array key body, because remember, if we're just performing a GET request, then the $_POST super global will be empty. And that means there will not be a body key. So we can't always assume it. I'll show you a little trick here, though. I'll show you the long form and then the shortcut.
I'll show you a little trick here, though. I'll show you the long form and then the shortcut. In the past, we would use the isset function. So look in this array and let me know if a body key is set or exists. And if that's the case, I can represent that with a question mark. Then we will echo out that value. Otherwise, we will echo nothing. Yeah, I don't know if we've reviewed this yet. This is the ternary operator. Think of it as an alternative syntax for if else statements.
So notice I can replace this. And this is the equivalent. I think it was introduced as part of PHP 8 or PHP 8.1. I'm not sure. Maybe, yeah, maybe 8, something like that. But yeah, this is the equivalent. So yeah, these two question marks here, technically, they are referred to as the null coalescing operator. If you want to get some points at dinner parties or lose some points more realistically. But yeah, it just checks if this value exists and is not null, which is basically what we were doing earlier. So yeah, if it exists, then echo it. Otherwise, echo an empty string.
So yeah, if it exists, then echo it. Otherwise, echo an empty string. All right, come back, give it another run. And yeah, I think we're in business here. So now if I paste in something that breaks the validation like we did before, notice that this time we see the validation error, but we don't lose what we typed into this textarea. And yeah, that's probably what you want. Okay, so now I think I've taken up enough of your time for this episode. But yeah, if we switch back to our controller, this does the trick. But as you can imagine, it could get messy very, very quickly.
But yeah, if we switch back to our controller, this does the trick. But as you can imagine, it could get messy very, very quickly. And then further, if we repeatedly perform these checks for every single form on our site, that just doesn't seem to make sense to me. And that's a little too much duplication for my taste. So in the next episode, we're going to extract all of this into a dedicated validation class. I'll see you then.
