As a consultancy we’ve encountered all kinds of code. Often times we inherit code from other teams, in which case we always make it a priority to review its style, structure, how it’s been deployed, if any frameworks were used, etc. Being able to understand and pick up another team’s work is often part of the job.
However, there’s no denying that sometimes things require extra discovery and adjustment to help course correct certain parts of a code base. n 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 Versions of LAMP
Running an outdated tech stack can result in costly bugs, security issues, or performance problems. For new projects especially, or legacy products that will undergo a full port, using an up-to-date LAMP stack helps start things off on the right foot.
One reason is that performance improvements are mostly gratis. 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. Even in the absence of performance problems, an up-to-date stack helps ensures products stay snappy and responsive.
Fully Enable Error Reporting
One of PHP’s warts is that it has, at least in the past, shipped with supressed error reporting. This has to be one of the biggest time sinks to the community – all too often forum or community posts can be found where a PHP developer is seeking help with debugging some undesirable behavior, only to have no error output to go on.
The fix for that is to set error_reporting to E_ALL in php.ini. For non production environments you may also want to turn display_errors on, although you’ll want to leave this off in production for security reasons in favor of only relying on error logs to capture error output.
With error_reporting set to E_ALL, PHP’s error reporting works with you by providing more detailed error output vs. against you by hiding it. With that, you’ll experience much faster debugging and a more enjoyable development experience because of it. You’ll even see things like deprecation warnings to give you advance notice of features or syntax that are slated for removal from the language – having more time to address these items is always a good thing.
Avoid Developing In Shared Environments
One common problem among PHP dev teams is developing in shared environments. That’s to say that things like a central database server or PHP installation are shared among multiple developers.
The problem with shared development environments is they’re a single point of failure for your team’s ability to work. Things like a network outage, or a developer making an erroneous server change, or a hardware failure (just to name a few examples) can all render your team non-productive for hours. Such teams operate with a high risk environment that requires careful and thorough communication when changes are required, and that shouldn’t be the case.
We feel the proper alternative is for each developer to run their own local development environment. By doing so each developer is under almost no risk from the factors mentioned above, and they’re free to experiment and make changes as needed to accomplish their individual project objectives without putting the productivity of others at risk.
One tradeoff to adopting local development environments is that they require more time for each developer to setup and maintain their own environment, vs. if they were to join a shared environment that’s already been setup and perhaps maintained by a team lead. But it’s worth it, arguably, because each team member should have a strong understanding of what it takes to setup a product’s environment, so the additional time to understand all the pieces involved is a wise investment. Things like file structure or location, configuration requirements, etc. all come to the forefront for each developer during their setup vs. remaining unknowns or hidden in the minds of one or two team members. Plus, automating environment setup is absolutely an option, if not preferred, which reduces the time required on the part of each developer to get their environment going.
Version Control
All teams, that use the LAMP stack or not, should be required to operate with some form version control. At the time of writing this Subversion is very popular, but Git, Mercurial, and Perforce are arguably better options. Regardless of what you choose or why, each team deserves a single source of truth when it comes to tracking state for their projects, and version control is probably the only reliable way to accomplish that. Worded another way, if your team isn’t using version control you’re likely doing something wrong.
To illustrate the value one only needs to imagine a production hot-fix scenario. I.e. some bug is found in production and is fixed ASAP. However, a team without version control is at higher risk of making the change willy-nilly and pushing it to the production environment, only later to have it overwritten when the same production environment receives its next update. The culprit is, of course, that the hot-fix was only committed to the production environment and wasn’t properly committed or merged elsewhere.
And so a proper workflow really depends on having version control. An alternative approach to the above would have been to commit the change to a hot-fix branch first, in the product’s version control repository. Even that much provides immediate benefit in that the change exists somewhere that isn’t easily overwritten and can easily be reviewed by all team members (if needed). From the hot-fix branch, sure, it can then be deployed to production, but it can also be easily merged into other branches such as testing, development, feature branches, local environments, etc., thereby removing the risk of being overwritten by an update.
Adopt A Framework
All teams should adopt some framework as a means to adhere to a uniform structure in which to solve a product’s various problems. There’s a wealth of good frameworks out there to choose from (Symphony and Zend Framework are two examples). Good frameworks are even likely to offer a very good foundation for less experienced team members to learn from. Such frameworks will typically provide great documentation resources, handy view templating (if that’s your thing), database abstractions, migration support, etc. But the overall benefit is that good frameworks allow teams to more or less hit the ground running with solving a product’s problems vs. reinventing architecture or conventions that a framework already provides.
Automated Testing
It happens all the time – something changes, something else breaks. It can happen when committing a simple change or when merging entire feature sets. Even worse, sometimes what breaks is so unrelated that it goes unseen or untested by QA because, well, why would something like an invoicing module break when all that’s changed was a fix to a user signup process?
Enter automated testing, probably one of the best “best-practices” of our time.
Any new team or product should really adopt automated testing, the benefits are just too vast. To start, by thinking about what tests should be written in accordance with a given change, developers are really empowered with a deeper understanding of the changes they’re making. Another advantage is that as time goes on, an automated test suite becomes an invaluable investment that pays large dividends toward catching breaking changes before they leave a developer’s environment. The accrual of tests for input validation, or tests that check when-this-changes-so-should-this, or that help ensure a user can not exceed their paid plan’s quota, etc. provide a tight, constant feedback loop as to whether new changes also introduce breaking changes. And the feedback loop is super fast, much faster than a series of commits and pushing changes upstream, where they may or may not be found by a QA team member.
Automated testing does not remove the need for things like QA, but it does provide far more stability and understanding of a product’s changes, especially over time. If you aren’t implementing some form of automated testing, start taking a look at PHP Unit and/or Selenium today.
Automated Deployments
The days of manually deploying web apps should be far in the past. That’s because manual deployments don’t scale, they’re too slow and error prone! Especially in distributed environments or when the number of target servers is high. Often time manual deployments are just flat out impossible.
But even for smaller teams or environments, automated deployments provide a fast, reliable, means to get changes into production (or test, or stage, etc.). Instead of having to handpick which files need to be deployed and then manually applying those to a set of servers, an automated deployment process might instead consist of a shell script or some build technology (ANT, or Maven). And in a simple command, it might access a given server, hook into version control and pull the latest changes, then apply database updates. With the process automated, it can happen very reliably and within seconds, each and every time, vs. a clumsy manual process that errors regularly somewhere along the way.
As mentioned, technologies such as ANT or Maven are popular in the Java Community but can also work for LAMP projects. Jenkins or shell scripts can also be just as effective, depending on the needs of the team or target environments.
Conclusion
LAMP is an extremely popular stack, in part due to its low barrier of entry. But that also means it’s very easy to race past that without considering, or even knowing about, some of the best practices worth considering for your next LAMP project. The start of every project is an opportunity to improve upon the last. At Solution Factor we believe the best practices above are some of the more beneficial ones to consider, and we hope you do to. They’ve helped increase not only the reliability of our products, but also the fun in developing rock solid applications for our users and clients.