PHP Coding Standards, Autoloading (PSR-4) & Composer - Full PHP 8 Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
let's talk about auto loading php standards and composer we'll cover how to use auto loader without composer first and then we'll go over some of the php standards and finally move on to using composer to manage our dependencies and handle autoloading for us in the last video as you remember we covered namespaces and created some classes but we had to use require statements to include these files there is one change i made here since the last video and that is i created this app directory and i moved all my classes in that app directory and i simply prefixed all my class name spaces with app so that way all of the classes of the application will have the app name space as the base or top level namespace as you can imagine requiring and including files this way can get very ugly very fast the more classes you have the more required statements you would need autoloading solves this problem php has a function called spl autoload register and it accepts few arguments and the first one is that we care about which is a callback function which is going to be our custom auto loading function and this function receives the fully qualified class name as the argument so let's simply var dump this class here and see what we get if i refresh the page we're simply getting the var dump of the paddle transaction object and we're not getting any var done from here that's because our registered autoloader function did not run because we have the require statements and php knows how to load these classes and therefore it doesn't need to run our autoloader so what autoloading does is that it automatically loads your classes interfaces and traits that are not already included or in other words are undefined let's comment these out and let's refresh the page now as you can see now we're getting the var dump right here and it's bar dumping the fully qualified class name and then we're getting error because he no longer knows how to load that class so what's happening here is that when you try to use or access a class php will check if that class exists if it does not exist before throwing any errors it looks for any registered autoloader functions and runs them one by one when you register oral loaders they go into queue and are executed one by one whenever class is not found we can see this in action as well let's add another autoloader here and let's var dump autoloader two and let's remove this class for now and let's bar dump autoloader one if we refresh the page we're going to get oil loader 1 and auto loader 2 printed on the screen that means that both auto loaders ran one by one and because this was registered first this runs first and this was registered second and this runs second you can pass the third argument as true to prepend autoloader in the queue instead of appending it to the end so we could simply use a named argument here and the third argument is the prepend argument that we could pass so we could say prepend true so now if we refresh we see that autoloader 2 gets printed first and autoloader 1 gets printed after so now that you know what autoloader is and how it works let's actually make it work to include our classes let me get rid of the second auto loader from here and let's change this back to var dumping class and add our custom rules so if i refresh we see the fully qualified class name now we cannot simply do require or include here we cannot do require class this is not going to work we're going to get an error because this file does not exist this is a fully qualified class name it's not the file path but we could get the file path from the fully qualified class name if we do a little bit of parsing right so our goal is to get something like this from this in order for the require statement to work now there are different ways to achieve this but i'm gonna go with the simplest way the first thing we can do is we can replace the backslashes with the forward slashes using the string replace function we can also append the dot php extension and if we refresh we're still getting there the next thing we need to do is that we need to lowercase the first letter of our string because the directory name is the app with the lowercase a so we can use php function called lc first and if we refresh now this matches to this but we're still getting the error the reason for that is because we need to use the proper path right here we are using dot dot to go up one level right right now we are in public directory but we actually need to be in var www app directory and to get this directory path we need to use php's magic constant and that is dir magic constant this will return the current directory of the file so in this case it will return var www public because that's where the index.php is and just to note i forgot to use this magic constant in the last lesson when i required all those classes as you can see here in the commented out code when i have require once dot dot you should use proper pathing here because if i were to run this index.php in a command line it will fail so adding the proper path using ph with magic constant will solve that so we can add this to this here with the slash and let's also rename this to path because it no longer makes sense to call it class because it's just a path but you could name it whatever you want you could name it class path if you wanted to so let's refresh the page and we're still getting the error and the reason for that is because now it's looking for this transaction class within the public directory we just need to go one level up using dot dot and now that should fix it so if i refresh the page now everything works now we can get rid of this bar done from here we can delete these require statements and if we refresh everything is working so now that you know how to do this by registering your own custom autoloader function let's see how we can actually do this using a tool called composer but before we get into the composer let's do a little bit of review of what coding standards and psrs are as you know php is very forgiving when it comes to code layout or structure you can put spaces tabs new lines make code difficult to read and it will still work just fine though you probably would not do that even if you didn't follow any conventions or standards because it would make it harder for you to maintain it so why would you follow any conventions or standards well let's say that you work in a team or that you work on an open source project you prefer to structure and write it based on your own style while other developers like to follow their own style and taste for example maybe you like to put curly braces on the same line of the control structures while somebody else in your team likes to put them on a new line you like to use camel case while somebody else likes to use snake case and so on this will lead to a lot of inconsistencies which makes code harder to read and maintain now take open source libraries or frameworks as an example an open source project can have hundreds of developers contributing to them if everyone followed their own convention the code base would be a big pile of inconsistent spaghetti this is why we have psr which stands for php standard recommendation which is maintained by php framework interoperability group or in short php fig this group was formed by several php framework founders and developers and since then a lot more members have joined the group so let's go to the psrs page here and we see a table so these are the currently accepted standards this refers to the psr standard number so we have psr1 psr 3 psr 4 12 and so on if we scroll a little bit more we have the draft we have abandoned and we have deprecated so psr1 is just the basic coding standard for example files must only use these two php tags here the first letter of each word in the class name should be capitalized constants must be declared in all upper case and underscores as separators method name should be camel case and so on if we scroll down you can see some examples and i'll leave that up to you to read you probably already follow most of these without even knowing it so let's go to psr 12 and let's review psr 12 a little bit so psr12 just replaces psr2 and adds more standards to it and it also requires you to follow psr1 in addition to psr 12. i'm not going to go through all of these i'll leave that for you to review but i recommend following these standards it's not a requirement but it's just a good habit that lets you write consistent code so if we scroll down we see the standards for classes properties and methods we see standards for traits which we'll cover later in the course we see standards for properties and constants we see standards for control structures like effel statements loop statements and so on so as you can see there is a lot of information here now you don't have to memorize all of this there are plenty of plugins available for example in phpstorm i could select which psr i want to follow and it will help with the formatting and will underline things when it's not in the proper format now if i hit ctrl alt l it's going to format it for me and it applies the psr 12 formatting so as you can see you don't have to memorize this i could also set the soft limits of the lines and so on if you're not using phpstorm simply google php code sniffer or psr plugins for your editor and i'm sure you'll find one i'm going to leave some links in the description that you could check it out if you want all right let's go back to the psr standards and let's open psr4 which is autoloading if we scroll all the way down we see some examples here also notice the 0.4 here it says that autoloader implementation must not throw exceptions and must not raise errors of any level and should not return a value so we are not returning any value but if this file for whatever reason does not exist it will raise a warning right so we can fix that by simply doing if file exists only then require it let's go back to the psr4 page and scroll up there is also the example implementation for it and as you can see this is more code than what we wrote here but essentially it's doing the same thing the good news is that we won't be needing this custom autoloader function here at all because we're going to be using a tool called composer to handle autoloading for us so should you follow standards in my opinion yes you should follow standards or at least some sort of standards and conventions if not psr as long as you stay consistent with whatever standard or convention you decide to use you should be fine you can also simply just follow the standards and conventions that the framework you use follows because in addition to psrs there can also be framework specific conventions and standards the key thing here is the consistency all right so let's move on to composer so what is the composer the composer is a tool for dependency management in php it lets you install various libraries and packages into your project in addition to managing your dependencies it can also help with autoloading and we'll cover that in a minute so let's get composer installed there are different ways you can install composer if you are on windows you can simply just download the composer installer and install it that way i'm using a docker so we'll be adding composer to our docker file that runs php for development that is fine but for production though it might be better to have composer as a separate container to save on resources but we'll keep it simple for now so i'm going to open my docker file which is in the docker directory here and we could simply just pull in composer as a command here now because we have the curl available we could use curl to pull in the composer installer and install it that way so this basically just pulls in the installer and installs it in user local bin directory with the file name composer so now we need to cd into the docker directory and run docker compose up and we need to rebuild our image so if we do that it should pull in the composer so as you can see it installed the composer the next thing we need to do is we need to ssh into our docker container and run the composer there so we need to run docker ps find the container name so that is program with geo app so i'm going to copy that and run docker exec dash i t then the container name with bash and now we should be in the container so let's clear that out and let's type in composer and see what we get these are all the available commands of composer and don't worry if it looks scary you probably will only use a few of these and you will get familiar with the others as you work on projects using composer the commands that you'll most often use are the composer require install update and remove you can find the packages that you want to install on packages website or in the documentation of the library that you're trying to install let's install a package to work with unique identifiers or uuids let's search for the uuid and see what we get we're getting ramsey uuid as the most downloaded package and with the most stars and we'll probably install that but i would advise you to before installing a package entirely because it has the most stars and downloads consider checking the repository and documentation and see what the package is actually about and if it matches with the requirements that your project has i've used this package before so that's why i'm going to install it so if you go in here we see that this is the package name and this is the vendor name so we could simply copy this and run composer require and paste that in and let's minimize that and actually close that out we run this and as you can see it's downloading not just the ramsay uid but it also downloaded some of the other packages that this package depends on so let's see what it did if we open the project directory here we see that it generated composer.json composer log file and the vendor directory and i'll explain what these are so composer json is basically your configuration file where you put all your dependencies in there are also many other configuration options that you can put in here but you can read about all the available options on the composer documentation but as you can see it put the ramsey uuid here with the version number here and don't worry about the version numbers for now now note that you don't have to use composer require to create composer.json you could simply use composer init to initialize the composer json file it will ask you a bunch of questions and you fill those out and then you will create composer.json file and then you can simply put the vendor names and version numbers that you want in there and run composer install to install those dependencies the other file that it generated is composer lock file now composer lock file basically locks your dependencies to a fixed state this log file contains all the packages and dependencies that your project depends on with exact versions so it locks your project to those specific versions basically you can and should commit this log file to your version control system like git that way you can ensure that everyone working on the project or you working on it from another computer are all using the same versions of dependencies so how does composer lock file get generated so basically when you run composer install if a log file exists it will resolve and install all dependencies listed in composer json file but it will use the exact versions that are listed in your log file if the log file does not exist then composer install will generate this lock file the same way composer require generated it composer require update and composer remove commands they will also update the composer lock file so when you run composer update it will update your dependencies based on the versioning that you have specified here and it will also update your composer log file don't worry too much about the versions right now you learn it as you start using composer more and more the other thing that got generated is this vendors directory and this is where all of your dependencies source code will exist so as you can see it has the composer here and it has our package here ramsay uid and it has all the other packages that ramsey uuid depends on so if we open uuid composer json file this is the package that we're pulling in and our project depends on but then this package also has its own dependencies and then our composer will pull those dependencies as well also notice the require and require dev here the main difference between the require and require dev is that require lists the dependencies for your project they need to be installed in production while require dev lists the packages that are needed for development the thing to note about required dev is that the dependencies from required dev will not be installed if your package is being installed as a dependency for something else so right now we pulled in ramsey uuid it only installed the packages that are in its required definition and it did not install anything that is in its required dev definition however if we were to add some kind of package dependency and require dev in our own composer json then when we run composer install it will install that as well but you could pass arguments to the commands to tell composer whether to install dev dependencies or not alright so we can close this out and there is also one more file here called autoload.php so this is the file that will let you autoload all of the classes of your dependencies now this autoload implementation is a lot more complicated than what we did and you don't have to worry about how it actually works but if you want you could take a look at the source code and see what it does we need to require the composer's autoload file so we can put that in our public index.php so let's do require and then we can use the magicconstantdir to get the current directory and then we need to go one level up because we're in public so we go one level up and then we can do vendor and autoload.php let's actually generate the uuid so i'm going to get rid of our custom oral order from here let's comment out the parallel transaction for now and let's do id equals new uuid factory and then we can simply call the method on that object which is uuid4 and this should generate the id for us so if we refresh the page we get id printed on the screen so as you can see this class has been autoloaded for us using composers autoloader now let's uncomment our parallel transaction class and let's do bar dump paddle transaction let's refresh the page and we're back to fatal error that this class does not exist that's because composer's autoloader knows how to autoload classes from the vendor directory but it does not know how to overload our own classes from the app directory we can fix this by simply telling composer how to autoload our own classes we can go to composer.json file and here we can add an option to autoload then we can specify the psr here so we are autoloading using psr4 and here we need to map our namespace to the location of that namespace to the source folder so our namespace is app with capital a and that simply maps to app with the lowercase and slash now if we refresh the page this will still not work we're still gonna get that fatal error because composers autoload files need to be regenerated if we open composer directory in the vendor directory here we see that there are some files here like class map files namespaces psr4 and so on these are the generated files so if we open the psr4 here we see that it contains the namespaces for our dependencies but it does not contain our own namespace which is app so to fix this we need to regenerate these files and we can do that by using a command called composer dump autoload and as you can see it says that it generated autoload files so if we open the psr for now we see our namespace has been added here and it's mapped to this location now if you refresh the page everything is working so as you can see now everything is working and we didn't have to use our own custom autoloader and we didn't have to include and require our classes the only thing we needed to do was to include this autoload file from the vendor in our index.php file before we wrap up this video i want to talk a little bit about classmap currently we are using psr4 to handle dynamic autoloading for us right whenever we add a new class under app namespace we don't need to regenerate the autoload file it will just work because it will just be dynamically loaded for you using psr4 rules and this is the preferred way during development but in production you want things to be as fast as possible right so in the composer directory here we see the autoload class map generated file while psr4 autoloading is already fast using class maps is even faster because dynamic autoloading needs to check file system before resolving a class name while classmate bottle loading will load the classes from the generated array and this is why it's called the class map it maps the classes to their locations in our class map though we only have a single element so we don't really have anything mapped yet other than this we can pass an argument to the composerdump autoload to load this array with the classes so we can do composer dump autoload and pass dash o as the argument and this should generate optimized autoloading so as you noticed it took a bit longer than before and right here it says that it optimized autoload files that contains 154 classes if we open the autoload class map now we see that this array was populated with all the classes that our application needs if we refresh the page everything will still work though if you add new classes then you have to run composerdump autoload with the optimize option again to add those classes in this array which is not that ideal for development right you don't want to be running this command every time so that's why using composerdump autoload for development is just fine but for production you might want to use the dump auto load with the optimize option so that it's a bit faster note that if the class is not found in this array then composer will fall back to the psr4 auto loading to load your class one thing to note here that you should not commit vendor directory in your version control system like git for example instead you should add this to your git ignore file that's it for this lesson there are definitely a lot more you can learn about composer and i might dedicate a separate lesson to the composer to go into more detail if there is enough demand for it so let me know in the comments if you would like me to make a separate video about composer versioning and so on thank you so much for watching i hope you found this lesson useful if you did please give this video a thumbs up share and subscribe and i'll see you next time
Info
Channel: Program With Gio
Views: 6,555
Rating: undefined out of 5
Keywords: advanced php course, autoload classes using composer, how to autoload classes in php, learn php the right way, object oriented php, php, php autoloading, php coding standards, php composer, php course, php in 2021, php oop tutorial for beginners full, php psr, php tutorial, php8, psr-4
Id: rqzYdHdyMH0
Channel Id: undefined
Length: 21min 49sec (1309 seconds)
Published: Fri Mar 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.