 Right. We are here. It's Thursday. It is workshop time or online workshop time or social learning space time, whatever you know it is. Welcome everybody who's joining us as you do come in. I don't have any requirements of you today. So as you're joining, please maybe just give us a shot as to where you're joining us from. While I introduced myself, my name is Jonathan. I live in Cape Town in South Africa, which is right at the bottom of Africa. I'm a developer educator at Automatic and I'm sponsored to work full time with the WordPress training team. And we're the folks that create tutorials and lesson plans and host workshops and all of those kinds of things on the learn WordPress platform. If anybody wants to in the chat, let us know where they're coming from. You're welcome to do so now. Mark says he's from, I always get this, I always struggle when I see this word. Snohomish, Washington. Aaron is joining us from Switzerland. Switzerland. Yes, that's in that's in Europe. Sorry, I went blank there for a second, believe it or not. Where Switzerland was. That's kind of scary. You had a word camp in Switzerland recently. If I'm not mistaken, my friend Remkes was tweeting and sending pictures from there next to Germany. Everybody knows where Germany is. I apologize. Mark Andrews is Baham, Mexico. Mark Andrews says I pronounce Snohomish perfectly. Thank you. I was corrected on my pronunciation of Nevada the other day. I say Nevada because I was brought up in South Africa. I find pronunciation is quite interesting because obviously, not obviously maybe, but most TV these days, especially most children's television is American cartoons and those kind of things. And so you notice your children start picking up pronunciations of words like grass and dance. And it's interesting. And then we have there's this TV show called The Investigators, which is from Australia. And my kids started picking up some Australian accents. So that gets interesting around the house. Matt is from Carbondale, Illinois. Yes, Aaron was, Aaron was talking about Remkes as we've come as performance talk. Remkes is a very, very good speaker on that topic. So if you didn't get a chance to catch it live, do look for it on WordPress TV. I'm sure it'll be coming out soon. All right. I think we can, I think we can get going. So let's move on to the announcements very quickly. So first of all, again, welcome to everybody. And thank you to Mark, who is co-hosting with me here today. Always appreciate it when I have a co-host. Please let me know if you can't see the slide right now. There's a slide with the heading announcements. And I will just restart the share, which I just did anyway because of the power. We are presenting in focus mode, but you're welcome to enable your video if you would like me to see your face. You're welcome to leave it off as well. I don't mind. You are welcome to ask questions. And normally I leave pauses for questions. Today I'm not going to leave as many pauses because today we're going to be doing things a little bit differently to the way we normally do things. So I'm going to say that if you have a question at any point in time, you're welcome to stop me because of the focus that we have today and the way we're going to do things today. So it's going to be a lot of me talking and sharing and discussing what I'm looking at on screen. Not so much interactivity from your side unless you want to follow the code along. So please raise your hand, either physically or if your video is on physically or use the raise hand notification in Slack or just post a question in the chat Mark will be keeping an eye on all those things. And he'll let me know if there are any questions I need to deal with. And if I'm going too fast, do let me know. I had one one participants in a workshop a while back who emailed me and apologized for pointing this up and I said to please don't apologize. I do as things progress sometimes start speaking fast it's something I try and be aware of. But if I'm rattling off because I'm going off on a tangent just stop me slow me down. And I'll gladly repeat myself. And then lastly, we will be posting this to WordPress TV afterwards and this is recording. So if you need to step out halfway through or if you're what if you didn't catch this live you're welcome to catch it on WordPress TV later. Then this is a slightly different announcement but if you today we're going to be stepping through some WordPress code that's we're going to be looking at code today. Welcome just to watch the screen and just follow along with me on the screen. If you would like to do it yourself and you are using the VS code code editor, you can install a plugin called PHP Intelli Fence, pH for fence. Basically, most most integrated development environments or ID is like PHP storm and others. And what's known as Intelli sense built in an Intelli sense is the ability to do things like autocomplete when you're typing functions, or clicking on a function name to take you to the function declaration so you can follow the code. Because VS code is not specifically a ID it's more of a code editor that you can then add plugins to to create ideal ID like functionality. You need to install a plugin to have the sort of click to follow the function name functionality. If you want to install this plugin now you can do I'm going to show you where it is in my VS code install so I've got VS code open here. You click on the code if you're in Mac OS it'll be code if it's Windows it'll probably be the file option. You go to settings and you go to extensions, the extensions pop up on the left hand side here. And then you could just search for the plugin name so I'm going to quickly get that name you don't have to do this today if you don't want to. I'm going to do this at a later stage if you prefer to do that. But it's basically PHP and then Intelli and then fence PH ENSE. There it is that's PHP code intelligence for Visual Code Studio. You click on that I don't have an install button right now because it's already installed but you click on the install button. It will install it it will ask you to restart your VS code and it will then be installed and ready to rock and roll. So you're welcome to do that now if you want to kind of follow along the functionality with me. You don't have to. If you're using other code editors like sublime text or those they might be plugins to do that as well I don't use those editors so I can't advise you. But what you're looking for is pH you know PHP code intelligence they call it or IntelliSense is the other way they describe it. So those are the two you'll actually see if you search for PHP IntelliSense IntelliSense I can't spell today. Then a couple of options will come up. Maybe I think it needs to else. There's another there's a PHP IntelliSense one and the PHP IntelliFence one and then there's an only one PHP there's a couple out there so I tend to use this one just because it was the first one that was recommended to me by somebody a while back, but you can try any of the others. And I'll show you how that's working in the in the. As we go through this. Okay, so let me close all of this down. And let me go back to my slides. So today we're going to take a stroll through the WordPress request lifestyle life life cycle. Better get that word pronunciation right now because I'm going to be saying it a few times today. So when I talk about the WordPress request life cycle I'm talking about the process that happens when you make a request to a WordPress postal page, or any other kind of content URL on the front end. What happens in the PHP code. What are the steps that it takes where does it go what does it do how does it set things up and all that kind of thing. We're going to be focusing specifically today on the front end execution of a postal page. I'm thinking that maybe in future sessions I might do one specifically on a dashboard postal page or a dashboard page and how that all works. We might also want to look at what happens when you make a rest API request because that's slightly different and loads slightly different things. And then I might also at some point might want to look at an admin age extra question so we see how that works and how that differs. But the primary focus today is going to be the typical front end request because I think it's a good idea to understand how that works. Before we do that though I want to show you something very simple that I created the other day and it's called mini press. I'm going to switch my VS code over to my mini press site. So you can see the code there and I'll explain to you why I'm showing you this. But mini press is literally as the name suggests it's a mini version of WordPress. If you want to find the mini press code I will share it with you now in the in the chat. I created this probably in about an hour and it's literally one PHP file for the front end, an admin folder and one PHP file for the back end. There's no logins. There's a schema.sql file which will create the post table in the database for you. You'll have to set up the database yourself with the username and password. You will have to make the username and password root and password. So the username will need to be root or the password will need to be password. And then your database name will need to be mini press. So this is not something you install on a production environment somewhere. This is just for playing around with locally. And I don't expect you to set this up now but if I go to forward slash admin which is the admin folder it'll fire the admin dashboard. And I cannot create the new post. So I can say this is my workshop. This is the content. Spell and I can create this post. It then stores it in the database. And if I go back to the front end and I refresh the front end of my site, there is my workshop post. Very silly, very simple, but it helps us understand how these things work. So if I open up VS code and I just show you the index dot PHP file of mini press the main front end file. You can see that right at the top it has some PHP tags. It then creates a MySQL connection to the database using the host, the username, the password and the name of the table, the name of the database. It then closes the PHP tag and starts rendering some HTML with a title and a heading. Then it opens up the PHP tags again. It gets the all of the data from the post table using the MySQL query function. And then it loops through the results by using the fetch source function, which fits an associative array from the result creates a row array out of it. And then you can output the row title and the row content. It closes the HTML tag and that is that is my front end defective. And this is in a nutshell, a very simplified version of what WordPress and a lot of other PHP based CMS is due. There's yet generally one file. It's usually the index dot PHP file. That is the what's known as the entry point to the to the request. It then does a whole bunch of things to set a whole bunch of things up. It'll eventually connect to the database at some point. It'll eventually run some kind of query to get the data from the database. It will then render some kind of HTML and in that HTML it'll loop through the results and echo them out to screen. And if you go back and have a look at the old B2 cafe log code, which is what WordPress was forked from and you go and find like version 001 or whatever it might be, you will see that the content is very much simplified, more similar to this than other things. But it's basically this is what it boils down to. So today we're going to be looking at this process from a WordPress point of view and what WordPress does when it does things. So if I open up my WordPress folder, or at least my site is called learn press. That's the one that I use for these demos. And then we will start with again, as I say, the index dot PHP file. This is typically the first file in any PHP based application that that the browser will hit when it makes a request. You generally set this on the web server. So the web server is generally set up to handle the index file. And it's sort of an industry standard that will be the index dot PHP file. Before we go on, I just want to mention one thing about query strings query variables and permalinks before we start carrying on about the index. When you go to, for example, the Hello world patch. So in this case, it's learn press test slash Hello world. That is what's known as a permalink. So if you don't know inside of your WordPress dashboard, there is a setting that you can switch permalinks on or off. It's under the settings menu called permalinks and your permalink structure can either be plain, which has this kind of format. So it has a question mark and then some code after it, or you can specify a specific permalink structure. Most WordPress installs are set up with a default permalink structure. And it's usually either post name or one of the others. I want to show you what happens if I switch it back to plain. And I want to show you what the URL to that same Hello world post was that we were looking at earlier. So you see now when I click on Hello world, you'll see that my I'm going to copy this into the into the chat so you all can see it there. My URL has changed from being Hello slash world to being question mark P equals one. Now that question mark P equals one is known as a query string. It's the way that you in a PHP environment can pass data to the PHP script and tell it to use that data going forward. So typically what would happen is in the dollar underscore get variable in PHP. Let me get the documentation to that. In this case it'll be dollar get because I'm it's a get variable for a query string. I'll paste that in the chat. Anything that you pass in a query string will be gathered together by the server not by the WordPress site but by the server and PHP language into this dollar underscore get array. And then you can access it in that array. So you'll see an example here. Let me just zoom in a little bit quickly. So here they are getting getting the name parameters. So in our in our example where we had passed in what was it P? Let me just move something out of the way here. We had passed in P equals one you would in the code be able to use the get array and then look for the P array variable and then do something with it. When you're working with permalinks, we go back to my WordPress site and switch my permalinks on and I'm just going to make it the post name for now. Now you're no longer using query strings. So now you're using what's known as a permalink and a permalink looks much better in the browser. It's a slash and then some kind of slug. It's usually lowercase with hyphens and those kind of things. And the way that that's managed is again on the server. If you open up, if you have a local WordPress installing, you open up your access file. You will see that these directives in your access file are what manage the permalinks. So you'll see this rewrite rule over here talks about the index dot PHP file and effectively all of this. What the stuff does is take the permalink and then send the request to the index dot PHP file but pass the permalink data along with it. If you're an Apache server, this is the HT access that works on every site. If you're an engine X server, these rewrite directives are set up on the server level in the conflict itself. But essentially WordPress needs to be able to work with both. It needs to be able to work with if you don't have permalink setup and if you do have permalink setup and we will look at how that happens later on. But it's just a good idea to understand that that is the case. All right. So let's go back to our index of PHP and let's look at what it does. So the first thing it does is it sets up this use themes constant. So whenever you see the PHP function defined, that means it's creating a constant and a constant is like a variable that can never change. So I can't later on say that use themes needs to be false. It set us true and it's always true. And then the very next thing that it does is it requires it uses this do variable, which means the directory this file is sitting inside. So in this case, it's inside of this learn, learn press directory. And it gives me the WP hyphen blog hyphen header dot PHP file. So let's open up that file. There's the blog header file. And I just move something out of the way here. And you'll see that what this file does is loads the environment. It sets. So let's step it through. So it talks about loading the WordPress environment and the template. But actually what it's doing is it's doing three things. It loads the WordPress library. Then it sets up the query and then it loads the template. So all of that if this variable WP did header is not set. So there might be other instances where that header has been set and then this content won't load. But by default, at this point, you'll see in here that hasn't been set yet. So when it gets to this point, it won't have been set. And then it'll start working through that process. You'll see it also sets the head at this point. So if this blog header gets included or required or used again, it's not going to run through this code. All right. Then it starts by loading the WordPress library and you'll see that it's using what's known as the require one statement. So let me open up a PHP manual URL for you there and I will paste it in the chat. So require and it's cousin or neighbor or brother or whatever you want to call it include our PHP statements. And they effectively say take let me find that code again. Take all of the code from this file that I'm requiring and then execute it. So I could actually just take everything from WP code for WP load, copy it and overwrite it over this code and then WordPress would still function the same way it is using requires and includes in PHP land is a way of separating certain common functionalities of code. And then just using one line to bring it all in. So effectively what it does is every time there's a require think about that code actually sort of filtering over from there and joining the main index of PHP file and eventually just have one big long index PHP file. There are actually developers out there I know a few who have built fully functional online applications with just one into one massively long index PHP file. WordPress hasn't followed that path it's separated things out a bit to make it easier to work with. But whenever you see require or include that's what's happening. Require month once means only get this file once so if some somewhere along the line somebody tries to require it again not going to plug in or a theme, it won't try and add it again. And then if you see the difference between require and include the only difference there is require will try to require the file and if it doesn't find that file it will actually report an error and stop execution. Include excuse me will report a warning but continue execution. And you'll see a little bit later how the difference between required include but right now WordPress is saying I require that file. It must be there if it's not there in execution straight away. All right. Now let's go to WP load and see what that does. So we're going to be now we're going to be diving into into code quite deep. Some of these things I'm going to skip over because they're not massively important for our understanding today. Some of them I'm going to spend some time on. If you see anything that I'm going through that you have questions about you're welcome to ask me, but I'm going to try and focus on sort of the high level important things. The very first one is you'll see that the apps path constant is defined. And this is basically saying the absolute path of the WordPress install. And it's basically the path that this file sits into. So it's this learn press folder. So whatever the path on the excuse me cuff on the server is that's the path and WordPress will use apps path then going forward. You will also see that many plugin developers will use the apps path constant and check whether apps path has been defined. Because if it hasn't, then the plugin is being executed outside of a WordPress install. And then usually they'll say, if not defined as path exit, don't continue with plugin execution. The next thing it does is it sets up some error reporting constants. This is basically how PHP reports errors. It basically only reports certain areas and turns others off and you can then change that on your depending how you got your debugging levels set up. Then the last bit of code, it's quite a long bit of code, but all it's basically doing is saying, find the wp-config.php file. And it looks for it in a couple of places. It looks for it in the apps path, first of all. Then it looks for it in the directory above apps path, in this case, one above wherever my learn press install is. And that's handy if you want to make your WP config a little bit more secure so you can actually move it to one level above your WordPress directory, which usually on a server would not be publicly available. And it means that somebody couldn't access your WP config. I wrote an article for one of my previous companies that I worked for to talk about this. Most managed WordPress hosts actually move the WP config to a higher level than the WordPress install because it gives you an extra level of security. If it's in the publicly accessible route and somebody does get hold of it, they have access to your database and that's usually a bad thing. And then if it doesn't find the WP config, then it actually triggers the WP admin setup config.php file, which tells the user, you don't have a WP config file, please create one so that you can install WordPress. Okay. So that's all that load does. It doesn't do a lot. Then once load happens, then it calls the WP function. Now we're going to see a bunch of things happen. So if I highlight WP and with that PHP tele-fence extension installed, I can click on it. You'll see it actually underlines it when I mouse over it. And when I click on it, it takes me straight to that function. And we're not seeing a lot of code yet, but bear with me, we'll get there. Sorry, let me go back one step. Yeah, so we've got WP load. I forgot, sorry, I forgot one thing. I forgot to talk about what WP config does. So let's go through that first. So WP config, we know pretty well. If you've set up WordPress yourself in the past, you will know that that's where you create your database name, user password and host credentials. It's also where your security keys are defined. It's basically all of your important data as a WP config. It sets up your table prefix. And then it sets up if you have debugging enabled or not. It's usually disabled by default, but when you're in development, it's a good idea to have it enabled the way I've got. It does another check for the app's path directory just in case it hasn't been set for whatever reason. And then it includes the WP settings file. So this is all still not the beginning of execution. Basically it's doing, you know, what's known as bootstrapping or setting things up. WP settings was what I meant when I said lots of things are going on. So you'll see that WP settings is still inside the app's path. So we will find it over here. So it's still in the root of the WordPress install. And if we open up WP settings, now we're going to see a whole bunch of code. So it defines the WP inc constant, which is the path to the WP includes folder. So that's this one over here. And if you have a look in your WordPress install, it's the one just below. I'm just scrolling up here. It's the one just below WP content. So WP includes is basically where all the rest of the WordPress functionality for the front end results. So everything to do with the WordPress instance, the query object, creating custom post types, taxonomies, all of those functions that you call from your plugins and your themes are typically in the WP includes somewhere. A lot of the functionality that powers the dashboard is also in WP includes. So sort of all of the core WordPress functionality sits inside WP includes. Then it creates some constants, sorry, some global variables, the version variable, the DB version variables and other variables. It requires the version.php file and the load.php file. It checks for required PHP version and MySQL extensions. If those aren't existing, then it gives the user some kind of error. And then it includes the base files needed for the initial initialization. So it's to do with plugins, default constants, recovery mode, fatal error handlers, all that kind of code. So all of that code is sitting separately. It's now just including that code into execution. None of that code necessarily gets run yet because it gets called later on, but it's now setting up that code to be to be filed. It sets up the blog ID and that then starts triggering off some functions that are sitting in those other files that we just include. So it sets some initial constants. It registers the fatal error handler. So when an error happens, that error handler can do what it needs to do. It sets the default time zone. It does some fixing of server variables. So there's different server issues across different setups. So it fixes that. It then checks is WordPress in maintenance mode. So are we busy installing plugins or themes? And if we are, we might need to show the user some kind of message. Because when somebody is requesting a postal page and maybe your theme is being updated, a file might be missing or changing while the update is happening. So you don't want to use it to necessarily see an error. It starts a loading timer. And then it checks if debug mode is enabled or not. Once it does that, there's some things to do with caching. There's an advanced cache.php drop-in. This is what caching plugins use to add additional caching to your WordPress site. So it does some checks around that. And then it sets up the default WordPress language directory for localization and translation. And then it loads a bunch more files. So all of those files that were required first is needed for the function things that happen. Then the next set of files that are required are needed for the next set of things to happen. So you'll see this a lot as we go through. Now it starts setting up the course. So it sets up the WordPress database object, includes the class and sets up all of your database things, sets up your prefix, your table prefix, and sets up your database variables. It starts any object caching if an object cache drop-in is present. It sets up any default filters. So when I talk about hooking into filters and your plugins and themes, the default ones get set up at this point. Then it starts checking Lisa, which file is this. So Lisa, the follower now is inside of the roots of the WordPress directory. And it's called the wp-settings.php file. It gets included at the bottom of wp-config, which gets included in wp-load, which goes from... So it starts at index, blog header, then wp-load, then config, then settings. And that's where we are now, about halfway through. Line 144 at the moment. Then it checks if this is a multi-site install and then it adds additional code needed for multi-site and defines a multi-site specific constant. And that's only if you have multi-site installed. And then it registers what's known as a shutdown function. So this is a special PHP thing that you can run code after all of your PHP execution has happened. You can create callbacks, hooked functions that will run after PHP code is run. And this can do things like what's known as garbage collection and flash object cache, sorry, output buffering and those kind of things. Not really the scope of what we're talking about today, but it's good to know that it exists. And then there is this short net check. So this is a constant. You'll see constants are usually always defined all in uppercase. What short net does is it allows you as a plugin or theme developer to create custom request endpoints. And if you define short net is true when the WordPress execution runs and it gets to this point, it will then stop any more execution of the WP settings page. This is very handy if you need something that only needs to, for example, do something with the database. So you may be creating a custom JavaScript Ajax callback that just needs to retrieve some data or put some data into the database. You can then enable short in it in your request, let it run, and then what it will do is it will be faster than if you didn't have short in it enabled. It's not something that's commonly used, but if you want to sort of speed up your asynchronous requests, that's one way you can do it. Okay, once that happens, then it starts loading the rest of WordPress. So then it loads all of the localization libraries. So everything to do with translations, text domains, local switches and all of that. It then runs the installer if WordPress is not installed. So this WP not installed will do a check, check if WordPress is installed, which means is there a conflict file? Is there a database? Do those things match up? If those things are there, then it'll just continue. If it's not, then it'll send the user to the, you need to install WordPress page. And then it loads most of the rest of WordPress. So you'll see there's a whole bunch of files here. I'm not going to go through all of them, but it's the capabilities file. It's the role classes. It's the user classes. It's the query class, which we'll be looking at in a second, the date query, the theme stuff, HTTP S detection, it's post type revision, post formats, all of the things that WordPress does, commenting, bookmarking, short codes, all of that stuff. Now it's requiring all of those files. So it's not running that code yet. It's just adding it into the execution process. So that later on, when it needs to call functions from those files, that code is available. So I'm not going to go through all of that because you can see the rest API gets loaded, the sitemap stuff, block support stuff, style engine stuff. And then, and then that, so that's 300. That's line. Where is it now? Line 136 to line 347. So that's about 200 files that are basically saying, right, bring me in, bring me in, bring me in, bring me in. Okay. Once those files are brought in or required, it starts doing some more setup. So it creates a global WP embed object. It creates the text domain registry for handling translations. It loads some multi-site specific files again. So multi-site functions, multi-site filters, that kind of thing. It'll set up some specific plugin directory constants. This is for checking with your plugin, WordPress plugin directory. It'll set up a plugin paths array, which is currently empty. Then it will load what's known as must use plugins. Now, if you've never seen must use plugins before, I'm going to share that link for you in the, in the chat. Must use plugins or plugins that perform specific functionality that will fire before any other. Sorry, I'm trying to send this to the waiting room, not everyone in the chat. That will fire before other plugins and your theme. So must use plugins. They are very specific. They're one PHP file. So you can't have multiple files in folders. They sit in a custom MU plugins directory, and they always happen before other plugins. So it's a great place to put things that must happen all the time in your WordPress installation. I can't think of any good examples right now, but if I do think of one, I'll let you know. So you'll see that must use plugins get loaded first, and then there is the MU plugin loaded action. So if you need to fire any functionality in your plugin or theme after the must use plugins have happened, you can use that action hook. Then you'll see it loads any network activated plugins. So those are plugins on a multi site. If you don't know how that works, when you install a plugin on a multi site, you have to activate it for a multi site network to then be able to activate it on individual sites. So it runs all of that first. It basically gets the active network plugins, loops through them and includes the main plugin file. There's also an action there for network plugins loaded, or network plugin loaded, so you can do that. Then it checks, again, more multi site stuff. It sets up some cookie constants. Cookies are browser things that do things like save whether you're logged into the site or not. It sets up some default WordPress cookie constants after multi site cookie constants are loaded, and it sets up any SSL specific constants. So usually that is like the URL to the HTTPS URL and those kind of things. It then creates any common variables. So it includes that vars.php file. And then what it does is it makes taxonomies and posts available to plugins and themes. So it's two functions that will create the initial taxonomies and the initial post types. So your initial post types are your post and your page, because page is a custom post type. And I'm not sure, I don't know offhand what your initial taxonomies are, but I think it's uncategorized or something as your initial ones. So what that means is because it hasn't loaded plugins yet, it means that those initial taxonomies and post types are available to your plugins. You don't have to register them when your plugins are registered. Then it registers the theme directory. So it gets the path to the theme directory and it just sets it up ready to be used. It does some more multi site fatal error handling. And then it gets to loading your active plugins. So again, it gets your list of active and valid plugins. So this happens. So this is a good point to remember. All of this happens every time a page or post request happens. So it has to get the list of active plugins, loop through them and include the main plugin file every single time. And this is where folks will talk about if you have plugins on your site that you're not using, don't leave them as active, because if you're not using them and they're active, they are slowing down your site. I'll be at a few milliseconds, but let's say you have a hundred plugins, but you're only using 10 of them. That means the other 80 that are active, if you leave them active, are causing some slowdown of your execution. So if you don't need a plugin on your site, either deactivate it, that still has a slight overhead, but not as much, or remove it and install it later when you need it. Little sign language. So again, it gets the plugin list and then loops through all the plugins and then physically includes that plugin file and then fires the plugin loaded action. So anything that you hook into after that will then trigger. Then it loads something called pluggable functions. Now, pluggable functions are a way of overriding existing, some existing WordPress functions. It's a way that you used to be able to do plugins in sort of earlier versions of WordPress. It's not used anymore, but because WordPress still supports that sort of backward functionality, it still includes that code. It sets any internal encoding and then it does some cash related things. And then it starts firing a couple of hooks so if you want hooks to run after your plugins, if you want any code to run after your plugins are loaded, you can hook into the plugins loaded action. Then it sets any constants that haven't already been defined, but that are needed. It does something called adding magic quotes. Magic quotes has to do with when you are sending data back and forth in your gets and post requests. It's about how it escaped single and double quotes. It's something that I remember having to learn to deal with when I first started working with PHP and I've never had to worry about it since moving to frameworks and CMSs, but you could go and dive into that code one day if you want to see what it does. Then it fires an action again, the sanitize comment cookies action, and then it now starts setting up some objects that are going to be used later. So it sets up the query object. It sets up a reference to the query object. I don't know why it does that. It sets up the rewrite object for your permalinks and your URL rewriting. It sets up the WordPress object, which is the core WordPress instance, the widget factory object for managing widgets, the roles object for managing roles and capabilities. So it sets up all of those core objects. Then it starts talking about loading themes. So there's a setup theme action that happens before the theme is loaded. It sets up any theme constants, any default text domain. It sets up the locale object, the locale switcher for changing languages. And then it gets any active and valid themes, which as you probably all know in a single site, is just going to be one theme. And then it basically includes the themes.functions.php file. So that's where when you do your netting of your NQ scripts and your NQ styles for your theme, but at this point that code is included. Not the theme templates themselves, just the functions.php. Then there's another action that fires, the after setup theme action. Then it sets up an instance of the site health object, which allows any cron jobs to fire. Cron jobs are basically scheduled tasks that can be run. And then it calls the globals WP and net method, which sets up the current user. The last thing it does is it checks the site status, which is related to multi-site. And then right at the bottom of that is the WP loaded action hook. So once all of that stuff is loaded, if there's any code you want to fire in your plugins and themes, you hook it into WP loaded. So that's the bootstrap. We haven't even got to the how it gets the data yet. That's just everything that's being set up before it's ready to start accepting the query variables and going and fetching the data. And you'll see we're already 40 minutes into this workshop. Okay. I'm going to take a sip of water now because my voice is a bit dry. If anybody has any questions so far, they're welcome to fire them off, but then we'll get into the actual core of the execution. Okay. So just to recap, we started with the index.php. It required the blog header.php. The blog header required WP load. WP load eventually required WP config. WP config eventually required WP settings. I like to think of WP settings as actually WP set up because that's actually what it's doing. It's setting up WordPress, but that's what the file is called. Stuart said, how does that compare to the likes of Drupal, et cetera? So that's a difficult one to answer because I haven't stepped through the way that Drupal does things in a long time. Generally, you're going to find that your older versions of Drupal, they recently switched to a more like a PHP 8 supported version. So they sort of stopped development on the old version and started a new version. So there might be some similarities in the old way of doing things because back in the sort of early days of the web, most folks had just an index page that did different requirements and whatever else. But a lot of it will be the same. If you step through, if you start on the index file of any CMS or framework, it will be including some files and then running some functions or setting up some objects within those files. One of the things that WordPress still does that other CMS might not do is the globals. So some CMS might just have one global, like they might just have one WP global and then everything is attached to that and everything is called off that global. WordPress has a few globals that are used. Sort of more modern frameworks and modern CMSs tend to not use globals because global variables are generally considered not a good idea, just because anybody can access them and hook into them. And also they can be difficult to manage sometimes if you don't have an iron what's going on. But to remove the globals from WordPress would take like a complete refactor and that would mean losing support for backward compatibility. So it's one of the reasons those still exist. But otherwise a lot of them are very much the same. But that doesn't really answer your question because I don't have the knowledge of those things in my head but it would be a good experiment to do one day. And install a Drupal site and then click through and see what the code does. Okay. So going back to the blog header, this is where everything is sort of managed if you will. We've gone through the load function. So we've gone through the load and the config and the settings and all of that. Now we're going to dive into the WP functions. I'm going to close the settings file. I'm going to close the config file and close the load file. And I'm just going to open up the WP file. So if you don't have IntelliFence installed that WP file happens in the functions.php file which is sitting inside of the WP includes directory. This is something that's very common from these sort of old days of the web. So one of the things that I did is any common functions would just be put in a file called functions.php and then just include it everywhere. One of the first things that I did when I started working for the web is I, before WordPress existed I built my own, well I wouldn't say before WordPress existed before I discovered WordPress. You'll find this story happens a lot. People will say I built my own CMS and then I discovered WordPress. But I built my own very simple CMS for the projects I was working on and I had a functions.php file which included my sort of commonly used functions. The other PHP online 1331 is the WP function and this basically sets up the WordPress instance or at least doesn't set it up. The setup creates the object but then this function calls the main method from the WordPress object with the query variables which kind of triggers things off. So if you want to have a look at what the main WP object looks like it's the current WordPress environments instance it's this WP global here. It's inside of the class WP.php file. So it's just class hyphen WP.php. This is what it looks like. Let me go right to the top so you can see it. So it's a PHP class titled WP and then right at the bottom of that towards the bottom of that file is the main method and I just want to mention something about naming conventions in programming. While this might be using the function keywords to donate this as a function, within a class you call a function and method. I sometimes confuse the two. I call it a class function when it should be a class method. It's just a naming convention. It's still a function. It still runs some code but the correct terminology is a class method. So the main class method is where we are now. We're inside of the class hyphen.php class hyphen WP.php file and what that basically does is it takes the query arguments. It first runs the WP init class method which sets up a whole bunch of things. I'm not going to dive into that now. Then it passes the request. So it takes the query arguments and it does whatever it needs to do to them. So it needs to filter them or sanitize them or whatever the case may be. It does that. It's diving to that quickly. So that pass request is inside the class.php file. It's here on line 136. So you'll see what it does is it first fetches the rewrite rules. So this is if we have the permalinks enabled. It gets the rewrite rules and it compares the permalinks. In other words, in our early example, slash hello hyphen world and it compares that to the permalink structure and then determines based on that string what the query string should look like. So if you remember earlier, we looked at it was, I think P, question mark P equals two, I think it was because two is the ID of that post. So it'll effectively will take hello world, which is the slug and it'll compare it to whatever else it needs to be and then it'll set it up accordingly. So that's effectively what all of that does. Then if we go back down to the main class method and it's called main, so it makes it confusing when I say the main class method, but I mean the class method called main. Once it's passed the query arguments, if the response, the return value from that class method is true, then it starts looking for the data. So the first one it calls inside of this WP classes query posts. So query posts does some more things. It gets the global WP, the query object. It builds the query string. So here it takes the permalink and turns it into the P equals whatever part and then updates what's known as the query vase on the WordPress object. So there's always this query vase variable sitting on the WordPress object. And then it uses the query object to query based on the query vase. I hope you're all with me there. If you're not, let me know. But if I now open the class WP-WP-QUERY file, which is going to be slightly higher up over here. There we go. And I go and look for the query method, which with a query function, which is difficult to search for if you just search for query because query is used all over this file. So I like to search for function space query. There it is over there. And you'll see what this does. It does some more initialization. It does some more passing of arguments at this point. It passes the query to the query vase and then it calls get posts. And get posts, if you click on that, or search for that in your WP-QUERY class, which is the same class that we're in, is now where it starts setting things up. So this is another one that's doing a whole bunch of stuff that we're not going to be able to dive too deeply into, but we're going to go over it very briefly. It fires off the pre-get posts action hook. So if you need to do anything to your query vase or your query before it actually gets the post, you can do that in there. And then it starts looking for any kind of query string parameters that it might expect. So for example, it might look for things like sticky posts or cache results or whatever the case may be. And it starts setting things up. And you'll see further down here, it looks for if the in parameter is passed. So if the query has the in parameter, then it's meant for month, but it sets date, time, so it does some things there. Later on, you will see if it looks for, let me find another good example, the search parameter. Okay, so here's one. If the post number is specified. So remember we looked at the early example, hello world was the same as P equals two. So by this point, hello world has been turned into P equals two in the array. So it looks for a P in the array and says this has been specified. So then start building that string. And you'll see it's now building up. This is the string that it's building up the sequel command that it's going to build up. It's going to run on the database. It looks for whether you've passed in things like post in or post not in these all global parameters you can specify on your queries, on your URLs. For example, here is the search pattern. If you ever do a search on a WordPress site, let me actually show you that. That's actually a good example. If I go to, I think my site will probably be easier just because I have a search bar at the top of my site. But if I do a search here for let's say Bob, you might not see the search, but you'll see my query string here is question mark S equals Bob. So that's the parameter that's going to be passed to the query object. And it's then going to look for that parameter and say, well, let me find the code quickly. If S is set up then pass the search results and create that query. So all this code is doing, and it's a whole bunch of code. You'll see there's more and more, it's going on, it's going on, is it's basically checking for certain query parameters in the query string or from the permalinks. And if those things are set, then it builds up that SQL query to run on the database. So if there's taxonomy, things are set. If it's running category pages or tag pages, if it's doing anything based on author, it'll set that up. If those things aren't set, it won't run that code. If those things are set, it'll set that up. So it's this whole query pass method, it does all of it, it builds it all up. And then you'll see as we get towards the end here, and it does joins if it needs to do, it does ordering if ordering is set and a whole bunch of other things. And yeah, it's lots of code. So you have to keep going, keep going, keep going. And down here on a round line, it does the paging, it does comments feeds. It's a whole bunch of things going on. It's a lot of code folks, so bear with me. Right down the bottom here. Yeah. Now it takes, so what it's basically done is it's set up all these variables, these string variables with the different parts of the query. And then right at the end, it actually puts that whole query together. So select the found rows variable, the distinct variable, the fields variable, any fields that have been specified from the post table, any join statements that are needed, any where statements, any group by any order by any limits. And then it runs that request. And then it does some more filtering. So there's a post pre-query filter. So you can run it just after the query has been set up if you need to interact with it for any reason. You'll see it sets up the request property on the query object as that request. You can then, there's filtering you can do. It sets up any caching. So if there's any caching enabled, it'll append to the query. And then eventually it'll run the query on the database. And then it will, let me just find a check quickly. It'll do caching. If ID is fields, then it'll do some things there. So here it starts doing, so here it says if ID is in the fields, then it'll call something from the database. It'll actually run that query and return that response. There's some more checks that it does. And then eventually it'll do some other things and split the query if need be. And then eventually it'll get down to where what's sitting inside of posts is ready to rock and roll. And right at the bottom here, let's just go all the way down past all of this. It'll eventually just return the post. It'll run the query on the database, return the results from the database. And if you remember when we looked at my earlier example, it was a lot simpler. It was just a MySQL query and the string. This is the same as all of that, but on a much larger scale with much, many more different possibilities, depending on the request URL, depending on what data you're requesting, but it will then return this dot post. So then posts is set up on the query object. So the data has been created from the database. It is added to the query object sitting in a memory, ready to be rendered to the screen. Okay, let's go back. So we've done all of that. So it was WP, let's go back there. Okay, it was main. So let's go find main. So we've done the query posts. So we're back to main. So we've done the query posts. So now the posts are either sitting on the query, on the query object or not. And if there are no posts on the query object, then the handle 404 will trigger it. So the handle 404 will check, are there posts? And if they are not, then it starts sending your 404 headers to the browser so that the browser knows this is a 404 page. Then once it's done that, it'll register any globals that need to be registered. So that's like the post global or the, so that you can access it in the template or any other globals, comments, whatever the case may be. Then it will send the headers. So it sends any browser headers that need to be sent. So your status codes or HTTP codes, that kind of thing. And then lastly, it'll run the WordPress action hook. You'll see that it runs this do action referee. Basically what that does is it passes the, this WordPress object to the action hook. So you can interact with it in your, in your action of callbacks. At that point, everything, all the data is set up in memory, ready to rock and roll, but nothing is being rendered to the browser. So then the last thing the step does is it requires the template loader. So you'll see the template loader is sitting inside the WP includes directory. So if we scroll up to WP includes and we find the template hyphen loader file, that's the one over here. Let's take this back up to the top. So what this does, first of all, it triggers a template redirect action. So this allows you as a developer to hook into that action. And if it's loading certain data, so you can check your WordPress object, your WP object, your WP query object. And depending on the data being rendered, you can hijack your, your template that's going to be rendered by default and render your own template. This is often something that is used by plugins to render a specific plugin template over the default WordPress template for that data, as an example. Then there's something about filtering whether to allow head requests. It seems to be related to a specific bug that was logged. So I'm not too sure what goes on there. But then the next set of things that the template loader does is it checks. Is this asking for the robots TXT? And if it does, it'll fire off some actions related to robots and then just exit out of execution at this point. Or it checks, is this asking for the fab icon? And if it is, it'll do that and then exit out of here. It'll check, is this asking for a feed? So as you might know, WordPress has feed, RSS feed functionality, then it fires off the RSS feed functionality and exits out of here because you don't want to load any templates at this point. You just want your default XML formatting. Or if it's a trackback, a trackback is a thing that happens in comments. If somebody links to a WordPress site and another WordPress site, it'll pull it in as a comment that's known as a trackback. If it's a trackback request, it'll run that code and then exit. So those are the default things that happen for your templates actually loaded. And then it gets down to the actual, is this, do we have a template for this content and is this loaded? And effectively what this does, if you look at this loop through the bottom here, it loops through this tag templates array. So the tags are functions, isEmbed, is404, isSearch. So let's use the isFrontPage1 as an example. IsFrontPage is a function that you can call to say, is the front page of the site currently being rendered? And it returns either true or false. So the code loops through these tags and then calls the actual function. So callUser function is a PHP way of programmatically calling the existing function. So it calls, for example, when it gets to this point, the isFrontPage template tag. And if it says true, yes, this is the front page being rendered based on the query object and the WordPress object that was all set up earlier. Then it will call what's known as the template getter function. So in this case, the template getter is getFrontPageTemplate. So what that does is that goes to your WordPress theme directory. If you remember, the functions were set up earlier so it already knows what the active theme is and goes through the template files based on the WordPress template hierarchy looking for a file to render for the front page. So if you specified a specific front page template, it'll load that one. If that one doesn't exist, it'll look for the fallbacks all the way back to the, I think it's index.php in the theme directory. When it finds that template, it will then, first of all, apply the template include filter. So again, you can change the current template before including it. It'll say, if there is a template, then include that template and notice that it's using include not require. So that means if it finds a template and then somewhere along the line in execution gets deleted, it'll try and include the file. If it doesn't find it, it'll just carry on executing. Won't cause any fatal errors on your site. So what you will end up with, which you might see often, is a widescreen of death. If there isn't, if it doesn't find a template for the content being rendered, then it checks if the logged in user can switch themes, which is typically an admin user. And if the logged in user can switch themes, it'll actually get the theme errors and then report those errors to the user. So this is a great way if you're working as an admin and you're testing things out, you can see, oh, there's a problem with my templates and you can fix that problem. And that's the end of the WordPress lifecycle. Once that's done, if you remember earlier, we said there was a shutdown activation callback and hooked into the shutdown process. Any code run in there might run, but effectively that comes to the end of WordPress execution. So the four main parts or the three main parts should I say are loading all the functionality using WP load, which calls WP config, which calls WP settings and sets everything up. Then calling the WP function, which sets up the WordPress instance data, sets up the WP query, makes the request of the database, gets all the posts and pages or whatever content taxonomies, whatever the case may be, depending on the URL back. And then finally, the template loader runs, which gets the correct template for the content being registered, renders that template to the browser, and then either, if it can't find it, throws an error or just fails recently. So that is my bit for today. It is a lot of information to take into. As you can see, there's a lot going on. There's a lot of code to dive into. I recommend if you feel comfortable with this, and if you have that IntelliFence installed on your VS code, or if you're using something like PHPStorm to sit and go through this process yourself. So go into the WP load and then go and have a look at what's inside the functions.php. There's a little side project that I would love to do one day, and I would love to take all the requires and all the includes and replace them with the actual code so that you kind of take it all down to literally one file. And I would love to see what that looks like, but it's all in separate locations because it's easier to manage that way, but that would be fun to do one day. Okay, any questions on all of that? Anything you saw, not sure of? Anything you'd like to know before we wrap up today? Plugable functions that is not used anymore. Is that a security concern, potentially? No, not to the best of my knowledge. As I say, it's the way that plugins used to work. So you still have to have a active registered file that can override the Plugable function for it to do anything. So the only way it's a security as soon as if somebody puts one of those files into your WordPress install, if that happens, you've got bigger security problems than overriding Plugable functions, if you know what I mean. So it's not a possible security risk like XML or PC is considered a possible security risk. It's just, it's the way that plugins used to work before they were plugins. You used to basically create a file and you would just drop it into a specific location and then you could override certain functions. But you had to have access to that location. So if you have access to that location, you have access anyway. Cool. Awesome. Well, I thank you for joining me on the stroll through the WordPress execution today. It's always interesting to me. It's always a good idea, I believe, to do this process yourself, to go through to understand what's happening. It's one of those things that somebody can't sit and do with you in an hour because as you saw, there's so much going on. There's so much code happening there. So what I tend to do whenever I'm working with a new framework or a new CMS is I just have a look at the, what we looked at today, the default thing that happens the majority of the time. So in this case, a page or a post is the thing that will happen the majority of the time in WordPress. So what does that look like? That gives me a good overview of where things are, how they work, what they're doing. And then later on as you dive deeper and deeper into things, you can understand how things all fit together and how they work. Great. Thank you all for coming. Thank you again, Mark, for co-hosting with me today. I hope you enjoy the rest of your Thursday and the rest of your week and your long weekend. If you are taking it, if you celebrate the long weekend over Easter, please enjoy it. And I will see you all again next week doing something else. I can't remember now what it is. Thank you all very much. Cheers.