 Thanks for coming. This talk is Does Your Code Measure Up. My name is Adam Kulp. You can find me on Twitter at Adam Kulp. My name is my handle on Twitter. So please feel free. If you have any questions or any comments, please feel free to put them out there. I don't know that we'll have time for questions at the end. We'll see how this goes. It depends on how many stories I get caught up talking about because as many people know, getting me to talk is not the problem. Getting me to shut up is usually a problem. So that being said, let's go ahead and get started. A little bit about me for those of you who don't know me. I thought that would click. No, that's okay. A little bit about me. I'm an open source contributor. And I'm also a sort of PHP certified engineer and a voting member on the PHP fig. I'm the host of Beachcast. If you haven't checked out Beachcast, please check it out on YouTube. I do a lot of videos out there on PHP and it's live coding. So I'm actually live coding on the screen. I try to keep it short instead of getting too long and long-winded with it. But please check that out. I organized the user group in South Florida and in the states. So if you're ever in South Florida, come out and check us out. And I also organized Sunshine PHP, which is where this shirt came from just two weeks ago. So come out down and see us. There are a lot of worst places you can be in February than Miami. So come down to Miami and check us out. I'm also a long distance ultra runner and photo enthusiast and a judo, a black belt and judo. So if you see those help want ads where they're advertising for the PHP Ninja, that's me. Now I bring up a lot of these things because most of my hobbies, most of the things I do are iterative. And I'm a huge fan of iteration. Whether it's long distance running, judo, development. You know, everybody knows that judo is a martial arts or a lifelong study. It's something that you practice that throughout your lifetime and you get better at it. Long distance running is much the same thing. How many long distance runners we have in here? Any long distance runners? We've got a few. All right, cool. So I'm an ultra marathoner. And what that means is a marathon is 26.2 miles. Ultra means more than. So I run marathons longer than 26.2 miles. I've gotten up to 76 miles so far. My time on that was about 14 hours. I haven't quite got to 100 miles yet. I would like to reach 100 miles. I just haven't got there. 76 is as far as I was able to get. Evading project managers, that's iterative. We get better at that as we practice it. And of course, code quality, which is what this talk is about, is also iterative. It's something you should do on an ongoing basis. You should constantly be measuring your code. And measuring your code comes in many different shapes and sizes. It could be tests. It could be code quality, as far as static analysis, things like that. It could be, you know, as far as performance. It could be lots of things. Now, if you find that your code quality measurements are something along this line, you're probably doing it a little bit wrong. You want to measure things and make it a little bit more quantifiable. You really want to have some good data behind it and be able to quantify the quality of your code and how you can improve that over time. So why measure the code? There are lots of reasons why we want to measure code. One of those is to be able to highlight bugs. So as you're doing code quality measurements, you can highlight the bugs in your code or highlight potential things that would indicate there might be a bug, right? Hopefully, you're able to highlight the bugs before they actually surface. And that's where code quality measurements come in, enabling us to do that. You can also improve the quality of your code, which has a lot of different side effects, right? So one thing is we as developers spend a lot more time reading code than we do creating new code. On average, I would say most developers probably read code about 60% of their time. The other 40, maybe even 30% of the time, is actually spent creating new code. So we spend a lot of time reading it. It just makes sense to make it cleaner, doesn't it? If it's cleaner, if it's more structured, if you know what you're looking at and you're able to structurally look at it and figure things out more quickly, then hopefully we can read our code a little bit less. So that's why measuring comes so important to be able to measure the quality of the code and make sure that it's clean. It also adds up to easier onboarding. If you have code that is cleaner, it's easier for people to read it and they're able to read it faster, onboarding becomes much less. We've all started with the company where we got it put into a new code base and we spend the first two weeks just getting our development environment up and running, right? That is not the way it should happen, but yet it does seem to be quite normal. If you have a good clean code base and if the quality measurement has been put in place and things, conventions are being used, you can get to a point where maybe you only have one or two days of onboarding, setting up the development environment and getting up and running. Oftentimes, I consult, that's my day job, I consult with companies so I spend a lot of time with new companies. Pretty much every one to two weeks I am working on a different code base. Doing that really is even much more important because I don't have a week or two to get up and running. I have to get up and running in hours. When I hit the ground at a company and I'm consulting with them, I have to be able to matter hours. I need to get up and running otherwise they're wasting money by me being onboarded. If you have good code quality, it makes onboarding much easier than I'm able to hit the ground running as a consultant. More often than not, my job as a consultant is to highlight that issue for them and help them make it better, but that being said, if the code is cleaner, I'm able to get onboarded much faster and it makes it easier for that. Also, it makes the code more testable. This is another reason why we want to measure is because if the code is, if we're measuring, excuse me, if we're measuring and the code is cleaner than chances are it's more testable as well. How many people don't have unit tests? I asked that in reverse because more people probably don't have unit tests than do. Nobody's willing to raise their hand. But I know there's a lot of you out there. And the reason we don't have unit tests is because it's not easy. It's not easy to have unit tests than chances are because the code is not real clean. The code measurement probably hasn't been put in place. So it makes it really difficult to write unit tests. If we're measuring and we're checking out the code on a regular basis, it makes the code more testable easier to put the test out there. Also adds up to satisfied customers. If we're measuring the code quality, we're improving the code, we can have much happier customers because we're able to put out new features faster. We're spending a lot less time with broken code, a lot less time trying to fix things and more time producing new things. Also, it's a matter of personal pride. We can be a little bit happier about our code. If you're working on the same code base and it's an ugly code base and you're working on it day after day, you just don't really have a lot of pride with it. Companies tend to have higher turnover if the code is ugly versus companies that have a nice clean code base and developers like working on it. And ultimately, it can also translate into higher income. If you're doing a better job coding, if you're able to create cleaner code, chances are you can demand a little bit higher salary. Now that might not be... It might be different from one place to another, but generally speaking, if you have James Titcom in a talk yesterday, he used the example where there was a tweet from Brandon Savage where if I have a developer for $25 an hour and I'm paying him to do something for many months versus somebody who's really good at it and able to do it much faster, that person's able to make more money overall. The company is actually spending less money with a higher paid person because they're getting it done faster. So anyways, it all plays into it. Now along those lines though, not all of us know how to create clean code. Not all of us know how to create great software. Usually, much like listening to music, right? If we listen to music on the radio or through some streaming service, what have you, and we hear a bad song, we know a bad song, right? You listen to it, you're like, oh, that's not good. I don't want to listen to it again. But we don't necessarily know how to write a good song, right? So that's where we need to continue to measure, continue to look at the code, and through that, we can write better software because not everybody knows how to create good clean software from the beginning, but through proper measurement, through getting this analysis done, then we're able to teach ourselves how to create something better. And we do that through code smells. Everybody familiar with code smells? Does anybody not know what code smells are? You can be honest, raise your hand. Nobody's raising their hand. You guys have way too much fear here, because I know there's a lot of you that don't. So the thing is, code smells, what we say about code smells is it indicates there might be something wrong, right? It's not spoilage. If it spoils, then it's not just smell, right? It's actually spoiled. But if it smells, that means there may be something. Now, I highlight a lot of things as far as code smells, and it doesn't mean that these are bad practices. It just means that they indicate there might be other issues underneath. And that's what code smells are. So code smells are not necessarily bad. They just highlight that there might be things. So some of the things we want to take a look at are like cyclomatic complexity. Cyclomatic complexity, that's a long word. A lot of you probably know cyclomatic complexity from now. I find that more and more people are learning it. So cyclomatic complexity, according to Wikipedia, is the count of number of linearly independent paths through a source code. Basically what it breaks down to is it's the decision points inside the code. Now, typically, we like to see within a function or a method, we like to see 10 or less as far as a cyclomatic complexity. And how that breaks down is something along this line where you have a function, and then you have a couple if statements. Well, each of those if statements, that's the decision. So your function, of course, is whenever you call a function, that itself is a decision. So you have a cyclomatic complexity of one just for the function, and then you have two other if statements as a cyclomatic complexity of three. So this function right here with just two if statements is a cyclomatic complexity of three. The goal is you want to stay less than 10. I personally set my goal much lower than that. I like to be right around six. I try to keep my cyclomatic complexity less than six. But that being said, cyclomatic complexity is a very important metric. If your cyclomatic complexity is high, chances are your code is doing too much. Because a function, after all, should do one thing. If your function is doing one thing, how many lines of code do you truly need to do one thing? And that's where a method comes in. I'll talk a little bit more about that in just a moment. And then, of course, we have code duplication. Duplicate code is also a smell. So by duplication, I mean actually copying code from one place and pasting it in another place. You might change a name, a variable name, or something like that. But for the most part, it is copying and pasting. Now, with duplicate code, we have what we call the rule of three is generally a good rule of thumb. And by the rule of three, that means that if you copy and paste something one time, it's probably okay. Now you have it in two places. In a perfect world, that's not a good thing. But in most cases, for everyday coding, you're going to have duplication of some sort. And then the second time, if you copy and paste it a second time, you kind of wince a little bit, because now you've actually copied and pasted it twice. But maybe that's okay. Maybe you don't have time to refactor it right now. But the third time that you're copying and pasting code, at that point, you need to clean it up, right? So the third time is kind of the threshold. You know, you're no longer wincing at that point. It is pretty ugly. It is pretty bad. So the rule of three is a good rule of thumb when it comes to code duplication of when is it time to break it out into its own function or service or something like that. Long classes is also a code smell. As a threshold, we like to see classes that are less than a thousand lines of code. Now, much like a function, like I said earlier, a function should only do one thing. A class is similar, but it should solve one problem. It's not doing one thing, it's solving one problem, right? So again, the class inside of a class is solving a problem and the methods, each method in that class is doing one thing towards solving that problem, right? So see how that breaks down like that? So anyway, a class, if you're solving one problem, chances are your class can be quite small and if your methods are each doing one thing, it really helps reduce the amount of code. And then class complexity is kind of, I mean, it is cyclomatic complexity, but now we're looking at the complexity of all the methods within the class. Having a high class complexity, you know, we use 50 as a threshold for the cyclomatic complexity there, meaning essentially you really, on average, you should have about five methods per class. Sometimes you might need more than that. Again, these are just smells. These are not saying it's bad. It's just an indicator that maybe we need to pay attention to it. Another thing, as I said earlier, a method should really do one thing, so we try to keep the method nice and small because it's only doing one thing. Unused variables, where we've created variables and then through some refactoring, now that variable is no longer being used. Now with IDEs, this helps because it highlights those for you. You know, in most IDEs, they're grayed out, so you know they're not being used anymore. It makes it easier to clean them up, but there's still, oftentimes, we see variables left behind. Back or overuse of comments. So comments are a code smell. Now, don't take this as Adam saying, don't comment your code. I'm not saying that at all. Please comment your code. What I am saying is that the improper usage of comments or having too many comments is a code smell. It indicates that there might be a problem. And why is that? The reason is because if you're leaving, if somebody is commenting a lot in their code, chances are they're trying to explain the code. You shouldn't have to explain code. If you have to explain code, then you did it wrong. Because code should be more simple than that. So generally in our code, we don't have business people following behind us and reading our code. They're not developers. They don't know how to read the code. So your comments don't need to explain the code. Developers are reading your code. They know how to program. You shouldn't have to explain it. Typically what I do with comments is I explain the intent of the code. So don't explain the code. It's like I don't need to know what the damn loop is doing. I just need to know what the intent of that thing looping is supposed to output. So that's generally when I use comments. As a general rule, I like to see about 25% of my lines of code being comments. And that includes duck blocks. So about 25% is a good threshold. And that's what I look for. I use another tool, which I'm going to talk about in just a minute, which is a PHP lock, PHP lines of code, LOC. And in there, it tells you the number of lines of code and it tells you the number of lines that are comments. And I try to aim for 25%. If I see more than 25%, I know somebody's over-explaining the code or maybe they're trying to explain it for a business person who's not reading the code in any way. Or maybe they're explaining bad code and we need to help clean that up. We need to help clean up the code. As an example, let's take this code sample here. I apologize if you can't read the comments, but that's okay. You don't need to read the comments. But the code itself, we have an if statement here. And any if statement is saying if employee flag and hourly flag and employees age is larger than 65, right? So obviously we're checking to see if the employee is eligible for some benefits based on their age or something like that. Now, as a way to clean that up, maybe we could do something like if. And in the if statement, we call the employee and we call a method in the employee called it is eligible for full-time benefits and we pass the ID. And then we can move the logic into that other function. Do I really need to comment this now? It's somewhat self-documenting. Now, code, it will never be self-documenting. Don't get into the trap of saying, oh, I want to make all my code self-documenting. That's not good. It's not going to work. Code is not self-documenting. But by making it named like that, I probably don't have to put a lot of comment before I call this if statement. Now, I might put a doc block on the method explaining what the method is doing, but I don't need to comment it right here. Again, so the idea is just to make it somewhat self-documenting, but at the same time, I don't need to explain the code here anymore. Another thing that we like to measure is global usage. And global usage is quite broad. First off, if you're doing the first example out there where you're defining some data as global, don't do that. You shouldn't be doing that. Just forget the word global even exists in the PHP language. Just do not use it. It's evil. It will catch you every single time. On the other hand, if you're using some superglobals, those are okay, but try to abstract those. Try to use in your superglobals, abstract them out to some library or something else, and then you're using them as data throughout your code versus using them as superglobals directly, but just try to stay away from global usage. And the reason we try to stay away from global usage is because, of course, and it is a smell, is because in your code, if you're defining something as global someplace and you ever run into difficulties, how do you find where it was defined? It's global. How can you find it? Do you have to do a find in your code base and maybe you have thousands of references to it because you made it global? So you're going to use it everywhere, right? And now, how do you find where you set it? And not only do you find where, how do you find where you set it, but how do you find where it was changed? Because it's global. You can change it anywhere, right? So that's why we try to stay away from it because it's just a pitfall you don't want to get caught up into. Another thing we want to measure is the end-pass complexity. Similar to cyclomatic complexity, the end-pass complexity is the number of paths through the code. Rather than the number of decision points, it's the number of paths through the code. And we try to keep the end-pass complexity less than 200. You'll see a little bit more of that come through as we're doing measurements. But end-pass complexity is something that really catches people by surprise. I've seen code bases where there are methods that the end-pass complexity is in the millions and trillions. It can get bad really fast. Generally, what it translates to is really slow code because if you have an end-pass complexity, it's really high. First off, if you have a code base that is very slow, the first thing I do is I run my static analysis on it to see my cyclomatic complexity and my end-pass complexity. And the end-pass complexity will really quickly tell me, okay, it's code. This is why it's slow. It's slow because of the code. It's not slow because of something else. Now, if it's not in the code, if the end-pass complexity and cyclomatic complexity are reasonable, then I know it might not be the code. There might be something else. It might be some connectivity. It's a database issue. But if the end-pass complexity is high, it means I need to look at the code. Maybe I need to break out some functions, bring down my methods. Often, my methods are doing more than one thing, and that adds to the end-pass complexity. And, of course, there's a lot of different things that we can also bring in as code smells. These are just the low-hanging fruit. These are the common ones that we measure and looking for our code smells. Now, there's a site out there, not a site, actually, it's on GitHub. Exocat is a Damian Segoi, and I'm probably mispronouncing his name a little bit. I love Damian, but I can never quite get his name right. But he's with Exocat, and he has a repo out there of Public Static Analysis Tools. It is a great repo because it highlights just a huge list of different tools that are available for you for measuring your code quality. Some of them are hosted somewhere else. Some of them are ones that you actually install on your system. Some of them are just PHP code that you execute to analyze your PHP code. But, anyways, it's a great repo for doing that. I like using some of the tools that were there. There used to be another page out there that was phpqatools.org that listed some of the common ones, but that has been deprecated, and now this is pretty much the one that most people look to. But I used a lot of these tools on an ongoing basis. As I consult, I would go out to customers' locations, and I really needed a lot of these tools, and what I found was they didn't always have the availability of the correct version to PHP to run them, or they didn't allow to install something. So what I did is the next logical step, I created a Docker image to allow me to do it. So I created a Docker image, so you can go out on hub.docker.com, look at my profile, Adam Kulp. I have an image out there, PHP code quality. You can also see it on GitHub. It's a very simple Docker image. It's not very complex at all, but it houses a bunch of QA tools that I use on an ongoing basis. So in about five minutes, I can get a Docker instance up and running using that image, and I can start testing code right away. And I do that. It's just one simple command, Docker run, and then pass it to the command, tell it where to output the file, and it's done. I can be on site somewhere, and within the first half an hour, I can start generating data of why they might be in trouble, and that's why they call me. They call me because they're in trouble. I don't have a job because people get into jams. I have a job because people get into jams. But that being said, so these are some of the common ones, and I'm going to talk about these. I'm going to show you how to run these. So again, on Docker Hub, I have the Docker image out there. I have other Docker images as well. There's another Docker image on Docker Hub. I actually only have like three images or four images. So there's PHP code quality. There's another one for PHP security. And then another one that is for PHP compatibility. So you can test your code to say, okay, I have a PHP 5.6 application. I want to get to PHP 7, which you should have already done by now. But if you haven't, it's out there, so you can use that. Now in the PHP code quality image, I also have PHP compatibility. But let's look at some of these tools. The first one is PHP lock. As a consultant, this is the very first thing I run. Before I even tell a customer how many hours it's going to take me to help them, I run this tool. Now the output for this is easy to run. You just call PHP. I'm calling PHP lock far. I'm telling it I want a single v for verbosity. I want to make sure that all the files that it's analyzing are .php files. I don't want to do anything else. I'm excluding the vendor directory because, of course, if I'm including a library through Composer, I don't need to check the code quality of that. Now, occasionally, I do check that in any way, but not on an ongoing basis, right? You only need to check your vendors once in a while to figure out if you're using code from somebody else that's bad and you can use something else. And then I tell it to pass to my project and tell it to pass for the output file. So this command just gives me one single text file, and in that text file, it looks like this. Now I know you're not going to be able to read the details of it, but this is the entirety of the report. It's a very small report. It tells me the lines of code. It tells me the amounts of comments. It tells me how many classes I have, how many namespaces I have, how many globals are being used. It tells me all that right here in this small little subset. Off of this, I can tell the customer how bad their code is because I know how to read this report, and with a little bit of practice, you can learn how to read it as well because some of these numbers indicate more than what they actually say they're indicating, right? You can kind of read between the lines and say, oh, you know what, you're cyclomatic complexity. It tells the average complexity per lines of code, and so you can look at a code base and say, wow, your methods are really long, right? You can see problems at a very high level really quickly. Now another item that I use quite often is PHP Depend. Now PHP Depend is more of an object-oriented related tool. It's not so much code quality as far as your coding standards and conventions and things like that. It is really more about the dependencies and how you're using your objects and how you're building object-oriented. So again, the command, it's a PHP file as well, so we're calling through PHP, we're calling the FAR file. We're telling it to ignore the vendor directory. We're telling it, first off, give me an XML output file, which gives you the details of the report, and then we're also using outputting some charts and some pyramids, and then I'm telling it where the path to my application is. And the nice thing is that you end up with some nice charts that tell you the size of your objects and how they relate to each other. It's some pretty decent output, as well as the XML file that gives you more detailed output of the complexity of your object-oriented objects and how they interrelate and everything else. It's a very good report, so you can see the stability of your application. Of course, the stability of your application, you want it to be very stable, you don't want it to have too much extension, a lot more... Yeah, we're skipping my mind, I'll think of it later. Another tool that we want to use is copy-paste detector. And this is, again, where that rule of three comes in. We can use the copy-paste detector. It's a very simple, we call throughPHP, we call the FAR file, we tell it to pass to our project, tell it to ignore any vendor files, because I don't need to do the copy-paste for somebody else's library, I only want to do it for code that I'm writing. And then I tell it where to output the text file. And it is very simple, it just tells you the file where it found. So here are like four different results. So it gives you the path of the originating and then the path where it found the copy-paste. And again, you can't see that whole line, but it does tell you the exact lines that were copied and pasted from one place to another. It's looking for exact clones. So if there's some differences there, it might not find all of them, but it's looking for exact clones. And for this one, for instance, there was a 36% duplicate lines, almost 37% duplicate lines, and it tells you the amount per the application. And so it comes in handy because then this can highlight where you might have had somebody who was doing a lot of extensive copy and paste. Maybe you had to get out a feature really quickly so you did some copy and paste just to get over that hump, but now you need to go back and clean it up, right? And writing bad code is something that we all do. We all write bad code. Even the best developers write bad code. But what separates a bad developer from a good developer, the good developer goes and cleans it up later. And they schedule time for that so that they can go back and clean it up. Nobody writes clean code the first time. It's impossible. If you do see me after this talk, chances are nobody will come see me for that because we just don't write clean code the first time. We clean it up over time, iteratively, through refactoring. Now PHP Mest Detector is another tool, this one I use all the time. I love this tool, PHP Mest Detector. It's also known as PHP MD. So we call the Mest Detector, right? There are many filters that you can use with PHP Mest Detector. The one that I use most often is the code size filter. And we call it, I call it again, PHP, PHPMD.FAR. We're telling it the path to the project. In this case I'm telling it I want to output an XML file and I want to use the code size filter. We tell it what to exclude. Of course we're excluding the vendor director. I don't need to run Mest Detector on somebody else's code, just mine. And then I'm telling it where to output the report to. And in this case it's outputting an XML file because I told it I wanted an XML file. Now the nice thing about it is it gives you some nice clean output where it tells you the file that it found something in and it tells you the result. Like cyclomatic complexity, right? We might have, you know, this one, the class dashboard has 1,030 lines. Our threshold was 1,000 lines for a class. So it flags this for me. So in cyclomatic complexity much the same thing, right? Do I have one for cyclomatic complexity up there? There's too many methods here. Excessive class complexity. Here's cyclomatic complexity, the very bottom one. Where the dashboard to cyclomatic complexity is 24. The threshold is 10. So we have a 14 cyclomatic complexity too high. And the nice thing is you can go through this and really quickly be able to clean up your code because it tells you where some of these things are. Now the code size filter highlights things like your class being too long, your methods being too long, your cyclomatic complexity, your end pass complexity. It's all about the size of things. That's why it's called code size. Another filter I use on PHP MESS detector is unused and it basically just looks for code that's not used. It's things that are no longer used. Another tool that I use is PHP dead code detector which is much the same thing. So if you're using the unused filter in PHP MESS detector, you're pretty much going to get the same result as the PHP dead code detector. But depending on your usage, maybe you only want one or want the other one. They give the same sort of output. Another tool that I use not quite so often, I mean a PHP MESS detector and PHP lines of code are my two go-to tools. But there's also PHP metrics at phpmetrics.org. Really nice tool. It has some good clean output. It is basically a PHP application. So you're calling it through a regular GET request. And then it gives you some nice clean output as far as showing you your objects and how they relate to each other and how they're lined up. PHP code sniffer is another very popular tool. This comes in really handy when you're doing coding standards. Everybody has a coding standard, right? That got pretty quiet. That's dangerous. So yeah, you should have a coding standard in your code. Now, there are many different coding standards out there. I'm a voting member on the PHP fig, so I like using the PHP fig. I'm not saying you have to use that one, but it's a good starting point at the very least. At least it's a good starting point. Now, when I ask if everybody is using a coding standard, of course, I don't mean is each developer using a coding standard. I mean is each team using a coding standard because everybody having a coding standard, but the whole team not following the same one, is also a bad thing. Everybody on each team should follow the same coding standard. And that should be discussed among the team to come to terms on a coding standard that is used in each code base. So code sniffer highlights this really quick because with code sniffer, it can sniff your code and look for the code smells we were talking about earlier, but it can also highlight coding standard issues. And you can create rules to tell it what to look for. In most, a lot of people use it via command line, but a lot of IDEs also have code sniffer kind of built in where you can have it watch your code interactively. I generally don't have it run interactively. I like telling it to run because I don't want it to nag me as I'm typing. So I generally do it that way. Now, along with code sniffer, probably my third most popular tool is PHP compatibility. So PHP compatibility is a set of sniffs that you can use with code sniffer. And the reason I like PHP compatibility is because it tells you if your code is compatible across versions of PHP. So probably one of the most common questions I get, especially over the last four or five years, is how can I tell if my code will work on PHP 7? I installed it on a server that has PHP 7. It seems to be working, right? But how do I know that all the lines of code will work in PHP 7 or 7.1, 7.2, 7.3? Hopefully, you're all on 7.3. I know you're not. That's why I say that. You should be on 7.3. But PHP compatibility is a great set of sniffs that tells you what you need to update in your code base to get there, right? And the command is quite long. It's actually two separate commands, but I chain them together with the double and percent. So the first one is where we're building the container. Actually, not in this case. In my image, it's building the container. But here, it's actually defining the configuration, right? So it's defining the configuration set, and then the second command is saying, okay, code sniffer now run using that configuration set I just told you about, right? So that's the two different commands and how they chain together. And then you tell it where to output your result file at the end. And the result file is quite straightforward. You know, it basically tells you, here's the file that we analyzed. We found two errors in this file, and here are the errors, right? And it lists those. It tells you the line of code that the error was on, and it tells you the details about the error. It tells you exactly what you need to change. It does everything but do it for you, right? So that being said, please use PHP compatibility, or if you don't feel comfortable doing it, you can always hire me and I can come and run it for you and tell you what you need to update your code. But many customers do that because we also do upgrade the code base for them. But I'm basically just doing what this report tells me to do. So there are some other tools out there, commercial products like Scrutinizer and some others. Some of you might be using Scrutinizer. There's also a tool from my company. I'm a consultant at Rogue Wave who acquired Zen Technologies a couple years ago. We have a Zen server in Z-Ray. Z-Ray allows you, it's like a browser toolbar that as you're rendering your application in the toolbar, it gives you static data on your application as it's running. It tells you the time it took each function to be ran, each class to be run, tells you all your objects, your variables, everything as you're going. Now, something that this talk really isn't so much about the performance. This talk is more about getting analysis of your code. But if you wanted to test performance, you could also use something like Apache Bench or there are some other tools out there too that are quite popular. But I like Apache Bench because in a nutshell, it does kind of relate to code quality because if your code is not written optimally, then of course your application is not going to run really fast. So Apache Bench gives me a good snapshot of that. I can really quickly throw, for instance, like here I could throw 10 connections at my application at one time and say, okay, how fast does it run? And it tells you the average time taken, like 10 seconds here, the completed request were 96. That's only 96 requests over 10 seconds. That's not very good. I might need to pay attention to my code, right? But anyway, it gives you a good nuts and bolts idea of where to go. Now, I've given you a lot of tools to run and I've showed you the commands for them, but you should be running these things automated. You shouldn't have to run them all by yourself. You should run them through an automated way, especially with continuous delivery, things like that. It should just be one item in your push, whether you're using Jenkins, whether you're using bamboo or any other continuous delivery method. Please automate it. Have these tools work for you. Now, generally, I don't fail a build on static analysis, but I do have static analysis generate reports as it's doing the pushes. Excuse me. And then I can analyze those reports afterwards. Now, I do usually build into my version control some code analysis. For instance, if somebody is trying to commit code that doesn't meet my coding standard, I will fail that. I'm not going to let you push code into the repo if it doesn't meet the coding standard. However, if psychomatic complexity is high, I'll let you do that. I'll let you commit that because we can refactor that later. But coding standard is something that shouldn't be a refactoring item. It should be something you just do. You should do coding standard to a set standard all the time before you even commit the code. Maybe the code's not the cleanest, but at least the coding standard is in place. So in conclusion, some of the things we covered here, make sure you're measuring everything, make sure you have some sort of tools, some sort of things out there to measure all of your code. Don't fear the results. Share them. Whenever I get the results from the continuous delivery and it's outputting the results of PHP mess detector and everything, share it across your team. Let everybody view it. Let the business view it. Let them see the results. Often developers will ask me, well, how do I get the business to allow me to do these things? How do I get the business to allow me to do PHP units and unit testing and all these other things? Because they're in a hurry. They don't want to give me time for that. You want to share these reports with them and you want them to see the trash that they're making you create. And then when they come back to you and they say, well, hey, our customers found this bug. How can you write this bad code? You can say, well, here's the report I've been showing you that I have to create it this way because you're pushing me into it. Put the ownership on them because they are the owners. You are just the developers. When you call somebody out to build a cabinet for you, you call somebody out to fix some plumbing in your house. You don't go back and blame them later if something broke because you told them to use substandard equipment and substandard sort of piping or what have you. You're to blame because you asked them to go cheap instead of going good. Well, if your boss is telling you to go cheap instead of going good, let them own that. Let them own it. And you can do that by sharing the reports. Reduce the complexity. Always reduce the complexity of your application. Always strive to get your cyclomatic complexity really low. Your end path complexity, keep it nice and low. Leave the code cleaner than you found it. Learn to smell problems in your code. You can use code sniffer and that, but a lot of times you can look at code and know that it's bad, right? You just look at it. That just looks confusing to me. If it looks confusing because you're spending 70% of your time reading code, if it looks confusing to you, it is confusing. So clean that up. That is a code smell. Now, through refactoring, you want to do refactoring in small little steps. You want to do small things. Make sure you have tests in place. If you don't have tests in place, now I'm not saying unit tests because I realize all code bases are not unit tests ready. They should be, but they're not all unit tests ready. You should at least have some form of tests. Even if it's just an Excel workbook with a, you know, test this, test this, test this, you know, line by line, even if it's that sort of test, you got to have some sort of test, right? Even if it's just that. Learn to love iteration. Development is iterative. Everything we do is iterative. Again, we don't write clean code the first time. We write clean code through iteration. Iteration is the easiest way to fix bad things. And you do it iteratively. Little steps. Don't refactor a great big thing. Refactor lots of small things. And do them iteratively. Some resources that I have, of course, on GitHub, Exocat, they have the static analysis tools listing. It's a great exhaustive list. phpmetrics.org is one of the tools that I showed you. Great tool. On GitHub, you know, you can find the docker image that I have there at php-code-quality. Zen, of course, if you wanted to use Zen Server and Z-Ray. Please rate this talk. You can also find some other information from me. I have a tech blog at geekyboy.com. I get a lot of traffic out there because I have a lot of good blog posts about code, coding, things along that line. Run Geek Radio. It's a podcast that I do. I try to get at least one episode a month out there where I talk a few minutes about running because I like to run a little bit. And I talk a lot about technology. But Run Geek Radio isn't really too technical. It's mostly soft skills. It's about how do you work better with the team? How do you advance your career? Things like that. That's the podcast. Meanwhile, Beachcast, that is technical. I'm coding on YouTube. I do it live on Twitch and then after I finish doing it at Twitch, then I export it out to YouTube so people can find it more broadly. Of course, you can find me on Twitter at AdamCulp. I think how many... Do we have some time for questions? Yes? Okay. So I have some time for questions, but that's it for the talk. Thank you for coming. Yes. That's why we can get hold of that PowerPoint presentation. So I'm going to link the presentation to Joined In. So as you're at Joined In rating this talk and leaving me feedback, please download the slides. I haven't linked them yet, but I will do that immediately following this. I made a couple of little changes prior to actually... I've given this talk probably 50 times, but I changed the slides a little bit and modernized them each talk. So I need to get a new version out there on SlideShare. If you want to search for the slides I'll do a search for AdamCulp. All my talks are out there. Anybody else? Any questions? Hello, at the back. Adam, that was a great talk. Thank you. I really enjoyed it. You taught me some tools. There's some feedback here, but I haven't used, so that's great. The question I have is which metrics do you find have the most impact with your clients? For instance, I find that empath complexity represents complexity better than cyclomatic complexity in a sort of visual way. Does that make sense? Yes, it does. So I think... I find differently. I find cyclomatic complexity is a much more important metric. If your cyclomatic complexity is kept low, chances are your empath complexity is going to follow. But the other way is not always true. You can get your empath complexity to be very low, but yet your cyclomatic complexity can be pretty ugly. So that's why I try to focus mostly on cyclomatic complexity. So at times, empath complexity is okay to be high. If you're using reflection, your empath complexity is going to be very high, and your empath complexity of one, or two, or whatever the case might be. So because reflection is... that has a high empath complexity out of the gate at a very little cost. So that being said, probably the most important is that understanding the lines of code and the number of comments of lines of code is very important. I would say that's my number two. And then empath complexity would probably be my number three. We have one up here. If there's any other questions, raise your hand so they can get ready to bring a mic to you. Have you used any AI power tools like Codesc and how do you compare all of these tools with Codesc, for example? So I have used Codesc, but very limited. I generally like to keep things close. So that's why I like using these tools because I can use them via command line really closely and I can include them in my deployment much easier. I don't like having a point of failure with something remote. But that being said, I don't mean it to be a bad thing. I just don't use it personally. So I can't speak much to it. Sorry. Anybody else? Any other questions? Hi, you mentioned failing commits. Would you use that for a pre-commit hook? I would. How would you check that, make sure the developer checked out that pre-commit hook? Because obviously you don't get that from the repo. Right. So in your commit hooks, as you're doing your polls, if you're using Git, for instance, you're doing a poll, your commit hook's going to come with it. So, yeah, you want to make sure that you have your hooks in there to run these tools, especially on commit. Now, I'm not doing like a PHP mess detector as a Git hook. I'm only doing code sniffer and running that versus the coding standard. I mean, that's the only thing that I really run as a commit hook. There are other things you might want to run as a commit hook, but that's just the number one as far as code quality measurement, that's really the only one that I run for code quality is code sniffer. It's lightweight, it runs really quick, and it will fail and say, sorry, you can't commit that or you can't push it. So, that's very important. The other quality measurements that I use are within the pipeline as I'm doing deployments and they don't necessarily fail a build, right? I don't necessarily fail a build, but I do want the artifacts so I can go back and look at those later. I do spend a lot of time reading the reports that are generated through the deployments, and that's ultimately important because then you can't properly manage a team if you don't have the metrics to manage a team. It's easy for a developer to get heads down and constantly jumping down rabbit holes and look very busy and they look like they're working really hard. You need to quantify that though. You need to know, is that person working smart? Not just hard. The only way to know if they're working smart is to properly measure the code. So, it's really important.