Join Kevin Skoglund for an in-depth discussion in this video Using a context for conditional code, part of PHP with MySQL Essential Training.
- View Offline
In this movie we're going to learn to use a simple programming technique, to make our code flexible and help us not repeat ourselves. If we have code that should behave almost the same in more than one context. Then instead of duplicating that code and making a few changes, its better to use a variable to identify the current contacts. And then use conditionals in the code to get the multiple behaviors that we want. The idea's extremely simple, but actually very powerful. Let me give you a quick example. Let's say that we have a context. The context can be morning, day, evening or night.
And then in our code, we can just say if the context is equal to night talk quietly, otherwise talk normally. This example is very simple, but it makes the point well. Context is a variable that's used, just so that we can base our conditionals off of it. Let me give you more of a real world example. Let's imagine that we have some code, and that code can exist in the header of our website, in the footer of our website, or somewhere in the body. We want it to behave almost identical in all three scenarios, with just some slight differences. We want to change the way that we apply margins to the item, depending on where it is.
So, instead of duplicating everything, we just make those changes using context. If the context is the header, then add margin on the bottom. If it's in the footer, add margin on the top, otherwise, add no margin at all. I think you get the point, and where I think we can make good use of this idea on our application is to differentiate between the public side of our website and the admin side. Right now, if we're on the public side, index.php, it looks the same, Widget Corp. Click over here, it looks exactly the same. I want us to have some way that we can quickly identify which area we're in.
So, let's open up header.php and let's do that, right here in the h1, that's the big blue block at the top. Let's just put in a conditional here that just says php If the layout context, I could just use the word context. But layout context is something I'm unlikely to use in any other way so I'm going to stick with that. If layout context is equal to admin, then just echo admin. Right? Nice and straightforward. So then we just have to set layout context.
So let's just come up here to the top, and PHP and it's not double equals it's just a single equal. So now, if layout context is equal to admin, we should see admin echoed right here in the header. Now, I'm forcibly setting it all the time right now, but let's just go back and take a peek at what that looks like. See? Widget Corp Admin. And I'll add that same thing up here to the top to the title as well,so it'll show up right here. I'll put a space and then, so if layout context is equal to admin, then it'll also say admin up in the title bar. Right up here at the top.
Okay so now I just need to make this conditional, right, right now I'm setting up all the time. Instead what I want to do is, I want to just jump over here and when I'm on admin.php, then before I load it in the header, I want to set the context equal to admin. And then when I'm on the public side of things, index.php, before I load the header, I'm going to set the context equal to public. Right, so in this case, it's set to public, and over here, in this case, it's set to admin. See how that works? Save that. So, instead of forcibly setting that here, we could just take that away for now.
And let's come over here and reload. And you see that we get admin on this side. When we reload here, on index.php, it doesn't show up. So, now we have a way to see. See, my tabs even show a different tab name on them. That's nice. So, now we know which area we're in, just like that. And one last step. It's good to set a default value for these kinds of things, so that if we forget to set it, we'll still have something here. So, let's say, if not isset layout_context, so if we forget to set it, then what do we want to set it to? And I am, instead of setting it to admin, by default I am going to set it to public.
I think, in general, it's better to set it to the more restricted version, the less privileged version. So, by default it will go to the public side. So, we actually don't even have to declare it in index.php, but it is okay if we don't. Now, we also need to, though, on the admin side, we're going to need to add this line throughout our admin area. Every time that we have some HTML, these three pages don't have any HTML in them, but edit_page does. We're just going to do a find for the header, and then we'll just want to put in our context. So, we set the context before we include our file.
Edit_subject, same thing, right before the header. index.php we've already done. Manage_content, and new_page, and new_subject. Okay. So, once it's in front of all of those, now I should be able to go to my admin area, and as I move around in the admin area It keeps that same look. It keeps the layout still always showing Admin.
The other place that I think we can make good use of this is in our functions. You'll remember that in our navigation we're finding all subjects in both our regular navigation and in our public navigation. But we only want to show visible subjects to the public while the staff area, the admin area, is able to see all subjects regardless of their visibility. So, let's go to our find all subjects, and what we want to do is make find all subjects context aware. So, the best way to do that is to pass in an argument telling it what it's context is.
Now you could just simply do context equals and you could say, you know, admin or public. But instead, I'm just going to do a different approach just to show you another way. Public and the default value is equal to true. So, we're going to pass in either true or false and by default it'll be true. And then whether or not it's public or not. So, if we are finding all the subjects and if public right? Public equals true, so we just have to say, if public, then we need to add this visibility to our query. All right? So, if we're not public, if we passed in false, then we won't have it.
Make sense? We're not calling it context, but it's the same idea. We're just using a variable to determine the behavior inside the function. We're going to do the same thing for find_pages_for_subject, because that also is part of the navigation. Public equals true and you could have it default to false but again I think it's better to default to the thing that has less privileges. And that's the public side of things. Now here it's a little more complicated because our where statement includes visible equals one. We can't just make this conditional, right? If we did, then we would have from pages and, that's not valid SQL.
So, we actually just need to rearrange things a little bit, sometimes it takes a little bit of creativity in how you write these and construct them. But I'm going to say from pages where subject id equals this, because that always happens. And then I'll just use my conditional here, and the conditional is the exact same one that I had there. If public, then add the invisible one, and you'll always just want to check and make sure that the lines still read correctly. That the constructed SQL reads correctly regardless of whether the if statement takes place. Make sure that you have any kind of ANDs that you need, that you have spaces, that you have commas or anything like that, that has to be added in there. So that's it, so if public is equal to true then we'll only find the visible ones otherwise we won't.
Alright so now both of these are now context sensitive. Both find all subjects and find all pages are aware of their context. So, we just have to then call the context. Well, public_navigation doesn't actually need to pass anything in because it can default to those values, right? We could pass in true, that we're in the public context, but I'm just going to leave it. I'm just going to say that it's fine. The only thing that I want to change is just in the admin side, when we find all_subjects, I'm going to pass in false. So, by passing in false as a value, it'll show be all the ones that are not visible as well as the visible ones. And then same thing for fine pages for subject.
So let's just try that out. Let's go over here. And we have our two navigations. Let's reload the page first of all and let's go to, Today's Widget Trivia. You can edit any one of them. But make sure that one of the subjects is equal to visible no. Right, so I still see it here. It tells me that visible is equal to no. But if I go to the public side, and I reload the page, it disappears. Right? So, I've got one function, behaving in two different contexts, just based on that variable, that I pass in.
Now, we're not quite done with this, because we do use find_all_subjects and find_pages_for_subject in other parts of our code, in the admin area. So, we're need to track those down. For example, when we edit our subject, we do find_all. You'll see find_all_subjects gets called here, when we're trying to figure out how many pages there are for the position. We want to make sure that we include all subjects in that list. Not just the visible ones, because we're in the admin area. So you want to track all those down. I'm going to leave that for you to do. Go through all the times that you find, find all subjects.
Find all pages for a subject and if you're in the admin area, you'll want to include that context. You'll notice that we do still completely repeat our navigation and our public navigation. We haven't combined those. I'm going to leave that as an extra credit assignment for you to do on your own. If you want to tackle that, you can actually have one function for the navigation. And you can pass in the context for whether or not it's the public navigation or whether it's the admin navigation. And you can have that context. Have both behaviors, so that we can have our code not repeated between those two.
But again, that's going to be an exercise for you to do on your own. The final point that I want to leave you with on this subject, is I want to show you that you can take this one step further by using an options array. The exact same idea, but instead of just having a single variable for context, you can have multiple variables and you just put those together into an associative array. An options array. Then you can pass that options array into your function. And then in the function, you can look at the different keys inside the associative array as if they were your context variables.
So, if options visible has been set, then we could do our visibility. This is a common pattern. And if you find that you need even more flexibility than with what we've been working with before. It's something you might want to consider. The other nice advantage that it has is a lot of times it makes for very readable code. Because for example, we can just very clearly see, that were asking for visible to be set to false. It's really very plain there. Where it's not quite as clear, in our code. It's not quite as readable that we're sending in just false as a single value.
Here, by putting a label on it, it helps us to identify it, as we're reading our code.
- What is PHP?
- Installing and configuring PHP and MySQL
- Exploring data types
- Controlling code with logical expressions and loops
- Using PHP's built-in functions
- Writing custom functions
- Building dynamic webpages
- Working with forms and form data
- Using cookies and sessions to store data
- Connecting to MySQL with PHP
- Creating and editing database records
- Building a content management system
- Adding user authentication