There is a bunch I could say to introduce this chapter. However, I think that by reading the first few paragraphs you will know what I'm talking about. For those who are experienced developers some of these items might seem a little basic, but there are reams and reams of PHP developers who do not follow several of these rules.
In other news, "You want to do WHAT with PHP?" is now available for purchase in the Amazon store.
Chapter 1: Networking and Sockets
Chapter 2: Binary Protocols
Chapter 3: Character Encoding
Chapter 4: Streams
Chapter 5: SPL
Chapter 6: Asynchronous Operations with Some Encryption Thrown In
Chapter 7: Structured File Access
Chapter 8: Daemons
Chapter 9: Debugging, Profiling, and Good Development
Chapter 10: Preparing for Success
Debugging, Profiling and Good Development
Permit me to rant for a moment. Not a big rant. Just a little rant. As of writing this sentence I have been a consultant for Zend Technologies for over three years. One of the things I do, among many others, is to conduct audits of customer applications. While it does happen, seldom are audits done “just in case.” Usually there are specific problems that I am tasked with. More often than not they are performance problems. Sometimes the problem is with PHP logic, sometimes with the database, but performance problems nonetheless. I am going to let you in on the secret to why I am good at what I do. It’s not because I’m special or have any type of secret knowledge. It is a button.
[Profile button in Zend Studio]
If you do not know what that button is, it is the Profile button from the Zend Studio toolbar. That is my secret. One of the very first things I do when I look at a new application is start running profiles on it. The audits I do generally last a week and it is imperative that I have a good understanding of what is happening in the application within the first day. It is also imperative that I have an understanding of what the main problems are by the end of the third day. This is done first with the Profiler, then with the Debugger, and then through using Code Tracing.
Don’t think that this is limited simply to the customers that I have worked with. PHP has a reputation of being a sort of script kiddie language. While this is not at all true, many PHP developers have not helped the cause by producing poor code. In many cases, really poor code. What is poor code? I remember reading a quote stating that programmers can spot bad code easily. What they have trouble doing is identifying good code. So it’s a bit of a tough thing to define what “good code” looks like.
I pondered this for a bit and did some Googling to see what others thought. Here’s a list of what I found.
Good naming conventions
Developed in small, easy to read units
In fair disclosure, I stole this list from Stack Overflow. Someone else wrote it on Dec 14, 2008. I think that the list is accurate. A lot of bad code misses the first item, meaning that it is not well organized or structured. Jackson Pollock would never have made a good programmer. While some claim it, I would tend to disagree that coding is an art form. It is definitely creative, but one of the purposes of art is to convey an idea via different and new mediums. Art doesn’t have to be maintained by someone else. Code does, and you should not have to “study” code to discover its meaning. The meaning should be plain and the code should be structured.
However, even a lot of code that is considered “well architected” fails on fifth point. Some of the worst performing code I have seen was because someone was trying to be too smart. The code fit all of the other parts but missed the part about not being clever. Overly clever code is, unfortunately, a bit difficult to document. One definition could be code that tries to guess what is going to be needed later on in a request; front loading program logic instead of loading it lazily. Another possibility could be using multiple levels of variable variables. Yes, you have to know how they work for the Zend Certification exam and, yes, they are useful to handle an abstraction layer. But each level deeper that you use a variable variable you decrease the readability of your code by an order of magnitude. Another example would be the overuse of magic methods.
My definition of what good code looks like is what is a good balance between reviewed “stream of consciousness” code, or spaghetti code, and the over-architected solutions. “Reviewed stream of consciousness” is code that you wrote in moments of inspiration that you have gone back over and re-examined, re-factored and unit tested. In the past, a lot of PHP code was written as a stream of consciousness. More recently though, in many ways, we are going to the other side of the pendulum and making our code so complicated that it’s just as difficult to work with. Additionally, many modern developers seem to have the idea that you can click a button, or run a command, or type some pseudo code and because our computers are so powerful we can have our application all but built after the command has been run.
This brings me to Kevin’s Framework Observation. It states that “the effects of the law of unintended consequence are inversely proportional to the ability of a developer to build an application without a framework”. Why is that? Because many times, when a developer starts using a framework they will often check their brain at the door. I cannot tell you how many times I’ve wanted to respond to people posting on one of several framework mailing lists that the answer to their question will be found by simply reading the framework source code. You are working with PHP, therefore you are working with open source code. If you are having a problem with understanding why a framework is doing something a certain way, pull out the debugger, which you should already be using prolifically, and find out why it’s doing that. One of my colleagues stated “You shouldn’t be using a framework until you know you need a framework.” Once you know you need a framework it is much more likely that you will have a full enough understanding to properly harness the framework. Don’t “use” a framework; harness it.
You may think that I am anti-framework after reading that, but that is most definitely not the case. I like frameworks because I am more productive when I use them. However, when I use a framework I make sure I know what is going on behind the scenes. Are you using Active Record, loading up a thousand objects to do some kind of calculation and wondering why your page is slow? Then you don’t understand the concepts of Active Record.
Most of the time, the problems that I have seen are because the developers do not know what is happening in their application. There really is no excuse for this. There are two main debuggers available, both of which support profiling functionality and both of which are free. For PHP they are the Zend Debugger and XDebug. If you are not familiar with those, or do not know how to use them DO NOT read any other chapters in this until you are proficient at debugging and profiling. Now, don’t get me wrong. PHP allows you to throw code at a wall and make it stick. But the developer is ultimately responsible for what gets written.
Every single one of the examples in this book has been run using the debugger. A lot of the code in the other chapters should be run by using a debugger so you can understand the actual logic flow and variable flow for the individual method calls. Even if you build something right the first time it is a good idea to go through it with the debugger. Why? Because if you built it right the first time there’s probably something wrong with it. To be honest with you, if I write some section of code logic that is beyond simple variable modification and it runs the first time through, my fear is that I did something wrong. And you know what? About half the time that fear is correct. Always check your work. A debugger is great for that.
This chapter is going to look at 4 different methods for gaining insight into your application and making changes more predictable. 1) Debugging, 2) Profiling, 3) Code Tracing and, 4) Unit Testing. We will also look at some steps that you can take on your local operating system to get lower level information about what it takes to get your application serving a request. All of the examples are going to be done with Zend Studio 7.1, but some of this functionality is available in the Eclipse PDT project (the most popular project on the Eclipse website as of this writing) as well.