At Solution Factor we’ve encountered all kinds of code. In times when we’ve inherited code from other teams we always take time to note how it’s been developed, style and structure, use of frameworks (or lack there of), the good parts and bad, etc. Being able to assess and work with other teams’ work is part of being a consultancy.
So inheriting code is nothing new for most developers. However, there’s no denying that sometimes things may require extra discovery and adjusting to help course correct certain parts of the project. In light of that, and having discussed this same topic a few times in the past month, we’d like to share 7 best practices we rely on to keep our client’s products, and our own, trouble free and enjoyable to develop.
Start/Stay With Up To Date LAMP + APC
Problem: Running outdated versions of MySQL, PHP, or not running an opcode cache, can result in costly performance problems.
Fix: Keep your LAMP stacks up to date. E.g. run at least MySQL 5.5+, PHP 5.3+, and APC.
There are so many benefits from starting and staying with an up to date LAMP install. Those range from added features, bug fixes, improved security, etc.
One of our favorites, though, are the performance improvements new versions of the LAMP stack bring. For example, PHP 5.2 vs. 5.3 performance improvements are well documented; the same goes for MySQL 5.5. In addition to what’s documented on the web, simple LAMP upgrades have helped several of our clients fix costly performance problems. This is one of them. And, keeping our own LAMP stack up to date helps keep our time tracking product, TimePanel, snappy and responsive.
In addition to MySQL and PHP, it should go without saying that every PHP environment should be running APC. APC is ubiquitous; the PHP team even decided to include it by default in PHP 6, although that version has since been tabled. Regardless, APC is a proven performance booster that’s safe and easy to install (e.g. apt-get install php-apc, or something similar). There’s no reason not to run APC in your LAMP environment.
In all, the performance benefits of up to date LAMP stacks are well documented and provide an easy way to avoid costly performance issues. That’s why each of our LAMP projects begins with the latest stable versions of MySQL and PHP, coupled with APC.
Proper Error Reporting and Logging
Problem: Improper error reporting is the biggest time sink PHP imposes on its community.
Fix: Set error_reporting to E_ALL in php.ini. For non production environments also turn display_errors on. In production environments leave display_errors off for security reasons in favor of relying on error logs to capture errors.
It’s a sad fact that most PHP projects suppress errors. By doing so, developers are forced to deal with more bugs, increased debugging time, and less reliable code. Even worse, is that as you can see from this post, improper error reporting is so pandemic the community seems conditioned to lean on it as a way to “fix” errors! Talk about an anti-pattern.
Instead, opt for an E_ALL error reporting level, preferably set in php.ini. That way all error types are reported and can be fixed immediately upon discovery. It’s also worth noting that in non production environments it’s advised to turn display_errors on, while in production environments it’s best to leave that off for security reasons in favor of using error logs to report errors.
Problem: Many PHP projects are developed in shared environments. Such projects aren’t portable, make too many assumptions about their environment, and suffer from slow development.
Fix: Start development in a local dev environments and move code upstream from there. This forces code to be portable from day one and facilitates faster development.
I’m still baffled by the amount of dev teams that like to build and maintain products in shared environments. Even worse is when they choose to work directly in the production environment (cringe!). Typically I find these projects started their life in a production environment, or that having dev, test, or staging environments was never taken seriously.
The problem with shared environments is that they increase the cost of development. This manifests itself in 3 ways:
- Developers step on each others toes, whether by simple code changes or server wide config changes.
- Developers become dependent on the network. This means putting up with slow file transfers or work grinding to a hault when the network connection dies.
- Slower development, b/c working on a shared server can remove the developer from preferred tools, or make them harder/slower to use.
For at least those reasons, prefer that projects start in local dev environments. This forces code to be configurable and portable from day one, and ensures developers are more productive by allowing them to work directly on their own machines, using tools they prefer, and aren’t dependent on a network connection.
Problem: Many LAMP projects lack a single source of truth. This results in questionable change history, overwritten bug fixes, and not knowing which code copy is authoritive.
Fix: Version control.
The projects we’ve encountered that don’t employ version control are far and few between, fortunately. However, when we do, adopting some kind of version control is one of the first requests we push to our client.
Even if you’re the only developer on a project, you should use version control. The benefits and purpose of version control are well documented. And, they go beyond these common false assumptions:
- version control is only beneficial for teams of more than 1 developer
- “I already use backup software, so I don’t need version control”
- it’s too complicated to use, or too complicated for non-developers to use
All of those are wrong assumptions to make. Benefits such as being able to:
- search revision history, or finding out who made what change
- diff local versions vs. repository versions
- have a single source of truth for the project’s code
… can’t be overlooked. So if you’re not using version control, start. It’s not hard, and it’ll make change management much easier. Version control is also a prerequisite to other best discussed later in this post.
For all its criticism, Subversion is fine for the most part; at Solution Factor we prefer Git and Perforce.
Problem: Many LAMP projects reinvent wheels. This means lost time and increased project cost.
Fix: Adopt a popular MVC framework.
With the wide adoption of popular MVC frameworks in the PHP community, there’s no reason to avoid adopting one. For example, if your team is writing their own database connection libraries, ORMs, or form helper libraries, you’re probably doing something wrong. Consider adopting an MVC framework. The benefits include:
- less development time, e.g. less time reinventing common wheels like ORMs or form helper libraries; popular frameworks include these for you.
- documented and easy to follow code structure
- easier on ramp for new developers
Problem: Simple changes often break something unexpectedly. Or, new developers come aboard and aren’t sure that changes they make won’t break something else.
Fix: Adopt automated testing.
Often times we inherit large projects, with some level of urgency to fix high priority bugs. We can usually pin point the problem easily, but for various reasons it’s hard to have confidence that what we’re about to change won’t break something else.
Another common situation are migrations. When moving a code base from one environment to another, how do we ensure that the new environment satisfies years worth of code changes and dependencies that the original environment had in place? Situations like this are where automated testing shines.
Automated testing is one of those things that once adopted, teams rarely move away from. The net positive automated testing yields is too big. Everything from migrations to testing single line changes is much easier when you’re covered by an automated test suite. And, if you’re constantly running the test suite against check ins in a dedicated build environment, you’re saving time and money by ensuring breaking changes are caught and fixed immediately.
At Solution Factor we pitch automated testing to all our clients, and certainly include an automated testing strategy for our products. Our framework of choice is the Zend Framework, which makes automated testing support easy via PHPUnit, but we’ve also blogged about how to include PHPUnit in other frameworks such as Kohana.
Problem: Manual deployments are slow, highly unreliable, and simply don’t work for many projects.
Fix: Adopt an automated deployment strategy. Automated deployments are fast, very reliable, and instill more confidence in the deployment process.
For many, automated deployments need no explanation. However, with most of our clients being start ups, small dev teams, or non-technical teams, we still encounter a lot of projects that rely on a manual deployment process.
The problem with manual deployments is that they’re error prone and time consuming. Everything from manual mistakes to having the code base in an unstable, in-progress, state while the deployment is being performed leads to problems.
Additionally, manual deployments don’t scale. Manual file updates may work for the smallest of projects on a single server, but not when you’re deploying to tens of nodes.
To get the most out of your deployment process, consider adopting an automated deployment strategy. At Solution Factor we rely on ANT, version control, and rsync to move code upstream from dev environments to test and staging environments, and finally to production.
In a practical sense, we’re able to move changes upstream in a matter of a couple clicks and a handful of seconds. This process also removes the risk of manual error, and has scaled to accommodate deployment to tens of nodes in various environments. Additionally, we’ve used our deployment process to make as many as 20 deployments in a single day. The reliability, speed, and confidence an automated deployment strategy provides changes the way you think about deployments.
Despite LAMP being a popular stack, it’s often easy to race past it’s low barrier to entry and consider some best practices that help ensure a reliable product that isn’t a pain to develop. The start of every project is an opportunity to improve upon the last. At Solution Factor, we’ve learned that adopting the best practices above has helped increase not only the reliability of our products, but also the fun in developing rock solid applications for our users and clients.