Defensive Programming in PHP

Share this article

Finagle’s Law of Dynamic Negatives:
Anything that can go wrong, will – at the worst possible moment.

Lightbulb with shield inside it

What Does “Defensive Programming” Mean?

Defensive programming, simply put, is programming with the intent to anticipate likely failure points. The goal is to circumvent those likely problems before they occur. You see the problem, right? There’s something inherently difficult with the advice “expect the unexpected” and it’s made many times worse when one alters it to “expect the unexpected and try to prevent it”.

Let’s look at some practical examples.

Conditional Statements

This is one of the easiest places to program defensively, and one where it’s easiest to be complacent. In many cases while programming in PHP, you simply won’t need an “else” case.

Hypothetically, you are working on a function and need a conditional. You only have three possible states for your particular variable at this point – and you have those covered in a block like this:

if($var == a){ }
else if($var == b){ }
else if($var == c){ }

There are no other possibilities, you say, and you move on with your code. Let me stop you there, though. I know that you know there are no other possibilities. And I believe you. But sometimes (unexpected) things happen. We forget about something. We look over mistakes. We end up reusing a bit of code outside of its originally intended scope. And all of a sudden we have leaking and sometimes silent error states because there’s no catch here. Make use of else blocks. Make use of default in switches. Use them to return or log an error so that you’re aware of what’s happened, should it ever happen. It may be an extra couple of lines of code, but it’s worth it when something happens that you did not expect.

Never Trust User Input

Have you heard this statement before? Most programmers have. It is a bit of a vague, generalized thing to say, granted. But it’s true. You should never trust user input. This does not mean that you assume that all users are crazed hackers out to destroy your application with a single set of well crafted commands. There is no need for paranoia. But, you should assume that users don’t know your code. They don’t know what parameters you need filled or how long the input can be. They don’t know what file types they can upload (even if the app tells them) or what size. And occasionally, they are a bot or a hacker and they are going to be trying to run scripts in their inputs. Sometimes even from inputs behind a login wall. How do you know when you can trust things like authentication or captchas to provide a safe barrier before users arrive at input forms?

The answer: Never.

If you never trust user input, then you never have a breach because you trusted user input. See? So always validate your input, and always ensure that you’re using appropriate techniques when handling data, especially when storing it in the database or retrieving it for display. For that matter – don’t trust input at all, even when from somewhere besides your users – input validation is always your friend. Check out Survive the Deep End: PHP Security and look into using a validation library.

Assumptions About Your Code

Don’t assume anything. If the previous two topics teach us anything, it’s that we should not make any assumptions. As programmers, especially when focusing on a single project for too long, we begin to assume a lot. We begin to assume that the user knows some of the things we know. Not necessarily technical details, but functional details about the program. We assume that the user will know how big files can be because… we already know that fact. Or that they’ll know that in order for the mailing script to… but no, they have no idea about any of that. This can sometimes matter more for front-end work, but obviously you still deal with user behavior and user input in the back-end as well, so it’s worth thinking about.

Another staggering assumption that many programmers make is the assumption of the obvious nature of our functions, classes, or whatever other bit of code we’re working on at any given time. A defensive programmer will try to think carefully about not only normal documentation and describing what a bit of functionality does – but they will also document any assumptions they are making about input, parameters, use cases, or any number of other similar things. Because we are all humans, and we sometimes forget things later. We also will all most likely end up with someone maintaining, extending, or replacing our code someday. If nothing else, recall that programming is happening in a world full of technological changes. If your application is still around in several years, it may need to be updated to a newer version of PHP and lose some of its functionality, or any number of components that it interacts with may change and necessitate changes in your own code. It is very difficult to predict these things, so good comments and documentation are very important.

Tunnel Vision

Another thing that can cause us to both forget good commenting practices as well as standards is tunnel vision. Tunnel vision happens a lot to programmers. You know the feeling. You’re solving a problem, you’re in the groove. You’re feeling isolated in your own little world, with your music (or lack thereof) and you’re just coding and all of a sudden two hours have passed since you last checked the clock and you realize that you’ve written countless lines of code without any comments. It happens to all of us at one time or another, but the important thing is to, at some point, catch that and add some where appropriate.

Consistency in Syntax and Naming

Consistency is a bit of a grey area – that delves a bit more into coding standards and the like, but it is relevant to defensive programming. In PHP, there are standards that can be followed to streamline your code for others who might view it, or for your own future use. But often, no one is actually making you code to standard. However, whether you’re coding to some set of standards or not, you should at very least be internally consistent – because it will make you less error prone. This applies especially to small syntax errors that take an aggravating amount of time to return to and fix after being caught. If you always use the same spacing, the same formats and syntax, naming conventions, etc., than you are less likely to make a mistake resulting in your misreading of your own code. You are also more likely to be able to quickly scan and find things that you need to find.

Conclusion

Beyond user behaviors and actions, don’t assume anything in general about your program. Assumptions are one of the biggest enemies of a defensive programmer. Don’t assume you won’t need that default case or else statement. Don’t avoid creating appropriate user error messages, alerts, logs, and whatever else you need just because you assume they won’t be needed. Your assumptions are often right – but we do not care about that. What we care about are the times that they are wrong. Always plan as though you may need to return to your code in a few hours, weeks, months or even years, or that someone else will – and document it accordingly. Don’t assume it will never need to be updated, extended, or maintained. That’s naive at best, and negligent in more cases than not. Sometimes just keeping the idea of defensive programming in the back of your mind can help you to estimate, plan, and program more effectively and more safely.

Frequently Asked Questions about Defensive Programming in PHP

What is the main purpose of defensive programming in PHP?

Defensive programming in PHP is a proactive approach to writing code that anticipates and prepares for potential errors or issues before they occur. It involves creating code that is robust and can handle unexpected inputs or actions, thereby reducing the likelihood of bugs or security vulnerabilities. The main purpose is to ensure the smooth operation of the software, even in the face of unforeseen circumstances, and to make the code easier to maintain and debug.

How does defensive programming differ from regular programming?

Regular programming focuses on achieving the desired functionality of a program. On the other hand, defensive programming goes a step further by anticipating potential problems and incorporating safeguards to prevent these issues from causing major disruptions. It involves validating inputs, catching exceptions, and checking for errors at every stage of the program.

What are some common techniques used in defensive programming?

Some common techniques used in defensive programming include input validation, where you check if the input meets certain criteria before processing it; exception handling, where you prepare your code to handle potential errors or exceptions; and assertions, where you make assumptions in your code and then test whether these assumptions are true.

How does defensive programming improve code quality?

Defensive programming improves code quality by making it more robust and less prone to errors. It encourages the use of clear, simple code that is easy to understand and debug. It also promotes the use of comprehensive testing to catch and fix errors early in the development process.

Can defensive programming help in preventing security vulnerabilities?

Yes, defensive programming can help prevent security vulnerabilities. By validating inputs, handling exceptions, and checking for errors, you can prevent many common security issues such as SQL injection, cross-site scripting, and buffer overflow attacks.

Is defensive programming applicable only to PHP?

No, defensive programming is a concept that can be applied to any programming language, not just PHP. The principles of anticipating potential issues, validating inputs, and handling exceptions are universal and can be used in any programming context.

Does defensive programming make the code slower?

While adding extra checks and balances can potentially slow down the execution of the code, the impact is usually minimal and is outweighed by the benefits of having more robust and secure code.

How can I start implementing defensive programming in my PHP code?

Start by thinking about what could go wrong at each stage of your program and then add checks to handle these potential issues. Validate all inputs, handle exceptions, and use assertions to test your assumptions. Also, make sure to thoroughly test your code to catch any errors.

What are the drawbacks of defensive programming?

While defensive programming can make your code more robust and secure, it can also make it more complex and harder to read. It can also potentially slow down the execution of your code due to the extra checks and balances. However, these drawbacks are usually outweighed by the benefits.

Is defensive programming worth the extra effort?

Yes, defensive programming is definitely worth the extra effort. It can save you a lot of time and headaches in the long run by preventing bugs and security vulnerabilities. It also makes your code easier to maintain and debug, which can be a big advantage in large projects.

Jeff SmithJeff Smith
View Author

Jeff works for a startup as a technical writer, does contract writing and web development, and loves tinkering with new projects and ideas. In addition to being glued to a computer for a good part of his day, Jeff is also a husband, father, tech nerd, book nerd, and gamer.

best practiceBest PracticesBrunoSOOPHPPHP
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week