6. MVC Model & PHP Singleton pattern | Build a CMS using OOP PHP tutorial MVC [2020]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
every cms needs some form of database where the content will be stored so that the administrators and the editors can update the content on their own in the cms itself and now we have arrived at the biggest part of model view controller the mvc the model itself and since this is the biggest part we will make it in several videos and explain several concepts along the way and here we have the hard coded articles from our controllers and as mentioned we need a database so that this is not hard coded here and the administrators when we have the administrator part of our application which is usually the biggest part and most complex part of the cms then we will have editors login and change their content so it cannot be hard coded here so we need to create a database but before we do that i've noticed that our css is not working anymore and that is because if you open the console we can see that there are several messages saying implying that the integrity attribute for the resources our bootstrap css are wrong so the resource has been blocked and the easiest way to do to fix that of course is to change the integrity attribute to the correct value for this css and js files and that is in our static page sorry it is in our layout default layout right and here we can see one of those integrity attributes you can copy the new integrity attribute from the bootstrap website however i'm just going to delete it because it's much easier to keep this tutorial working so let me just remove all the reference to the integrity attributes i might as well remove this cross origin anonymous and if i refresh now i can see the css is back online and our website looks a bit prettier so let's create a database and i'm using phpmyadmin here however you can use any client that you like the php my admin just comes with xampp and it works as i need it to so i will create one database in this case called darwin's cms by the way this cms is called darwin because it will evolve all the time and here i will make one database or one table sorry name pages with three columns and the field it needs are the id as being as integer and primary key out increment the next field is title which will be varchar with 255 for example and the content that will be text and now we have our table in our database where we are going to store the pages and since this is the object oriented tutorial we are going to make one object called page and we are going to actually put it into one folder named model by the way the model part does not mean that you need to have a model module folder you can name the folder wherever you want the mvc is more about the structural organization of the application not the file structure itself so even this source folder and this model for the folder and the services folder that's all the model of the application regardless of the folder name and this page will be inside this model now this class is going to represent one page in our cms so it is basically a simplified version of the active record the orm pattern and we will create three fields here one that is the id of the page one field that is the title of the page and one field that is the content itself that is going to be displayed and we also need some method uh that we will use to actually find the page that we are looking for uh if you remember we have the home page the content page the about us page and there will be much more pages because that's the cms the content management system it will have a lot of pages a lot of content and one easy way to do that is to have one public method named find by id for example and it will accept the id of the page that we want to fetch from the database and that we want to work with and here we would need to connect to the database in order to get the information that's actually stored in the database right so we will create one database connection and we will use the pdo for that and let's see what the php documentation says about the pdo and here we can see one way to connect to database my database is called darwin cms it's on the localhost default i am just using the default user which i'm hoping that you are not and let's exit here just to see if our connection is working now all that we need to do is to use this page object to find our page from the database and to do that we need to write an sql which will basically select from pages where id equals to id that we are passing in and we need to prepare this statement and then we are going to execute with our ids actually i will split this so that we have the statement as well prepare and then we are going to run the statement execute because we are going to need this statement to fetch our data and for now let's just bar dump this page data to see what is in it if we are getting if we are reaching the database at all in order to do that we need to let me close all of other pages we need to go into our home page and instead of this hardcoded variables here we need to use our newly created page object let's just include it into index page index.php model page and i see that this template is a lowercase so we will actually need to change that one to rename that to the upper case so that each file that is a class starts with an uppercase so that it matches the class name and now in our homepage let's create one page object and let's find by id the page number one and if you remember our database is empty so let's put some data into our database by giving the home page title and content and if i call the home page now let's see what happens nothing happens because i'm on the contact and on the home page we see that data coming from the database right home page title let's just check it and let's rename it home page title from database just so that we are sure that our data is coming actually from the database right now let's continue with our page object and let's update all these fields here that we created so after we find by id we are going to say this id equals to page data let's see what the page data returns so it gives us the id associated array value or the key and we'll do the same for the title same from the content if i remove this bar dump here and i go to home page now we should remove these variables here and instead of this one we need to pass our variables page object as a key and our newly created object page as a value and we're going to use this page object inside our template rather than parsing it here if i refresh there is an error and that is because the static page has not been updated to work with the object it's still worth trying to work with fields so if i go to our static page instead of echo title we are going to echo page object title same for the content now if we try that one it works great and we are basically connected to the database we have our model and we have our primitive active record pattern now this breaks some of the good practices however it is allowing us to progress easily throughout the course and also show why some of the practices exist in the first place why some of the patterns exist and also what problems are they solving so stay tuned for next episodes where we are going to fine tune improve this code and show some of the common pitfalls of object-oriented programming and this is one way to do it and we can continue like this however if you remember our plan on the homepage controller is not only to display the page data but also to get some seo data get some page data get some additional configuration data and uh if we for each object in our application in this case the page but if we have something like a news article or something like a faq article or contact page or some specific model here if in each of those we connect to the database then we are in big trouble because the connection to the database is quite expensive operation and we ideally want to connect only once to the database in our application so how can we do that well we can of course move this component connection to the index somewhere in our bootstrap of in the bootstrap of our application this is much better because now we have one connection that is inside our index page and we have also cleaned our page model so that it is a bit more solid or it means that it's following the good principles in a way that it's uh it has a single responsibility it is only worrying about getting uh the data and manipulating the data for the page from the database rather than taking care of the connection to the database as well so this works a bit better however now we have another challenge we need to pass this database handler from the index through our controller here so we need to give it here and then in our home page controller we need to go to the controller and put it here inside the constructor then go back to home page controller and then provide it to the page object itself and it is not ideal solution because some then we are restricting controllers so that they must get the database connection it can happen that some controllers do not need database connection at all and also passing that data all the way around is a bit difficult to follow where the objects are going and where are they coming from and also in case that we need to redirect from one controller to another controller in a single connection in a single call we will have to pass database multiple time potentially opening multiple database connections and we do not want to do that we want to keep one database connection to a single and one and only database connection so singleton can help us preventing having multiple connections here so the non-singleton approach makes it possible for us to have one resource that should be only one multiple times so that we can suddenly get a multiple instances of that one object and that is basically something that we don't want in our case of the database and the reason is that we are allowing a new database object to be created on multiple places and if you suddenly get multiple people working on the project you basically don't have control of what they can do with this object somebody might do it by accident or by not knowing what is the right way and suddenly you have multiple connections and that takes quite a lot of time to debug and to find out why is some page slower why is database struggling when you get a bit more traffic in your application so the singleton helps us here by making sure that we can only get one instance of our database object so it allows that you can have one class and only one single object made from that one class for your entire application which is actually useful for database connection here as we want to connect to database only once and this is or it was the most popular pattern that everybody wanted when the object oriented got introduced in php because this is the closest thing to the procedural procedural programming meaning that you don't have to think about the scope of these classes as singleton classes or objects are just there when you need them as the functions were before the object-oriented program and it's usually better to use a dependency ejection instead of a simple singleton however i think that it's useful that you know it as you might encounter it is sound application and even modern frameworks and applications like laravel for example it has a singleton binding method in a service container as it has its purpose although in laravel it works a bit different so it addresses some of the concerns that a plain and simple singleton has singleton however comes with some disadvantages and the main one is that it can be difficult to control throughout application as it doesn't have a clearly defined scope you do need to manually hunt it down it also breaks a bit of single principle in a sense that the class is both creating instances in the get instance method and it is providing the functionality by allowing you to query the database and to actually connect to the database and you might argue that the singleton is not a bad thing per se but it introduces dependencies that will make your life more difficult as it sort of works like a global function but in a class it is therefore more difficult to test programmatically especially if you include it in some other classes directly instead of injecting it as dependency it's not impossible but it's a bit difficult so singletons have their place in my opinion but you just need to think about its traps you need to be aware of the drawbacks and you should use it when you absolutely must have only one object of that kind although in php this is sort of not truly single object as each server requests will make its own object but a bad example of using singleton is if you're trying to go the easy route and you just want to avoid dependency injection passing some object and you just want to quick and dirty access to some objects from your models and from some of your classes and objects do not do that do not write bad code on purpose so we will now make one single tone in practicing our code but does this explanation make any sense do you have any questions about it i kindly ask you to like this video and subscribe to my channel if you really like it and i would also like to know how many of you are actually following this series and coding along in this tutorial if you are following please write me in comments at what stage of progress you are are you working as a developer have you just started with object-oriented programming are you more interested in the cms or the op or these presentations should i explain things in more details or is this the speed that uh suits you since we are so early in the project i can easily change the course of action so i can explain some things better so that you can get more more out of it new comments are the only feedback i have so please make your voice heard also i am working on a full course on all popular design patterns that is coming out very soon maybe if you would like a free preview of the course when it's ready as well as some discounts in the beginning please go to applicableprogramming.com and register your email in the form so that way i can send you the link once i record some lessons there is a link to the website in the description so let's make one singleton in our application and the best place for that one is maybe in a source where you can have one database connection class now there are several things that we need to take care when we are creating a single tone one of which is to make our class final and that will basically prevent anyone extending our class and thus making new instance of it we don't want to do that we want this class to be final as it is so database connection and in order to get a singleton type of object in class we also need to use the static fields like instance in this case which will be initialized as null and i will show you why now right now and we also need one field that is also static that will contain our actual database connection in this case so this instance field will contain the object instance the class instance and the connection that is where our database connection that dbh database handler will be the one that we have from the home page this one and in order to get that instance we need one method that is also going to be static in this case public let's call it get instance and this one will basically return us the instance you need to use self here because this class will never be initialized as an object but before it just returns it it will check if this instance is still null it means if the instance has ever been created so if the instance is null it will actually create so it will create itself as a new instance and it will become clear very soon why and now there are a few more things to make sure that our database is actually singleton so that we protect it from creating multiple objects and one way to do that is to overwrite the constructor to make it private i'm missing one parentheses here and by making the constructor private we are sure that nobody can actually construct any objects out of this class there are a few more methods that we need to take care of one is the clone method we do the same here we just overwrite it and make it private and the same for the wake up method the wake up method is used if somebody is serious serializing our objects to maybe store them in a session or database or whatever but when you do unserialize or the wake up of the object or a class the php will actually create a new object instance and we don't want that that's why we are overwriting the wake up and now we basically have the instance control under control here so we are just making a new instance and always returning the existing instance if this object or this class this method is being called multiple times that is basically making sure that we get only one instance of our object class but we now need to connect to the database and we need to make one public static function static means that we don't need an object to call this method uh let's call it a connect because why not and we will just pass some parameters like the host of the database database name user and the password and then we are just basically going to store into this connection so it will be the self connection we are going to store our connection from the index this one this is what we are basically making so let's move that one here this is connection string and we're going to grab this string and just adapt it so that it is using these variables for the host for the database user and the password marvelous now we can just remove this connection to a database and we are going to connect using our database connection so let's just include our database connection here and let's connect to date so we need the database connection and we just called connect for now we are going to hard code variables here they might come from some settings file or some setting methodology that we have for now it will be here as mentioned before this whole bootstrap and this auto this will be moved to how to include out of the index.php file database name and the user is root password is empty now when we are connected to this database we need some way to get this method to get this connection because you remember it's private so we need one method here public that will just return our connection get connection this can be done on differ multiple different ways you can get it from here you can make it public but it just complicates things a bit then you need to take care of some other things this one works just fine so we will return self connection right and then we can get this connection here or rather than here as we did before we can now use our controllers and we can let our controllers get the connection when they need it so here in our controllers now we can ask for the database instance or the database handler instance in this case so we get the instance here and from the instance we can now ask for get connection itself this will be database connection and we can pass this connection now to our page which will then accept it via constructor and we always know that this page needs a database connection so that way we can say that this will be one private field database connection and set it and then if everything is good we can just use this uh database connection or database handler here to prepare our statement now let's just try out out of curiosity to refresh the home page and we can see that we still get data from the database we can confirm that by changing the title in the database and we can see that it's responding now we are basically back to beginning but we are avoiding to pass this database connection throughout our controllers however from the controller we can get the instance of database connection and then we can pass it to our page the controllers are not perfectly object oriented in this case as they are suddenly introducing some dependencies they should be cleaner but we are making sure that we have only one and only one connection to the database and we can see that if we go to the get instance into our database connection sorry and if we just do a short dump here where we are connecting to the database if we refresh we can see that we have only one connection to the database let's test that by getting multiple instances and multiple connections in our controller and even if we're going four instances and we are asking for four connections we can see that we only have one connection to the database and that is the whole point of singleton to make sure that we are connecting to database only once so our get instance it will either create one instance or it will return it multiple times and we can see that here if we go to our database connection you can use the debugger that we used in previous episodes to x debug to trace where the code is going however i will just simply dump this so that we can see and i can say we are creating a instance and i can say we are returning the instance if i refresh now we can see that we are connecting to databases connecting to the database we are creating an instance and then we have four times returning the instance so still the instance is created only once and the connection to the database is made only once which is very important so let me remove these dumps if i go to about us page it is broken and that is because if you remember the static page is now changed so that it is expecting the object rather than the simple variables that we had before so let's quickly fix the about us page so that it works the same way as the home page i don't need these connections here and while i'm here i will fix a few more things i need first to get this about us page content inside the database so i will just insert this page quickly since we are in database now this is the page 2 our about test page let's see if it works and the about us page is working again however we are not hardcoding it anymore it's coming from the database as expected while i'm here i notice that the about us controller file name is not correct so let me rename that one and let's fix that into our public index as well so it will be about as controller let's see if it works it works the contact page is now broken so i will quickly fix that one and i will just speed up so that you don't have to wait for me and since we have three pages here i will put them all in database and we will do the same thing for the contact us landing page or the content of the contact us form and if you remember our contact us page now it's working but we have already submitted the form let me clear the session and now we have the content form but we don't have the data above because we are using the contact us template which should which should now also be changed so that it works with the object there is this one and instead of title we need page object title and the same for content and our contact page is working we have the thank you message and if we try to submit already we have the you have already submitted the form however all of this data is now coming from the database so we basically have a dynamic content management system working it is getting the data from the database and displaying it dynamically how about that it was very easy as i mentioned and i will include this database into the source file on the github so that you can play with it you don't have to type it manually and here is a joke for you [Music] you
Info
Channel: Applicable Programming
Views: 3,141
Rating: undefined out of 5
Keywords: php singleton, php singleton design pattern, php singleton pattern, php, singleton, php design patterns, php model, php model view controller tutorial, php programming, php tutorial, php tutorials, singleton pattern, beginner php, applicable programming, learn to code, mysql
Id: JETtm6MFm3I
Channel Id: undefined
Length: 28min 23sec (1703 seconds)
Published: Sat Sep 05 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.