Document your code!
9:11 AM in PCI Compliance, PHP, Programming by Vic Russell
I was recently contracted to work with a small company to enhance and expand their PHP application. The people were polite and the environment was quite relaxed.
I started the first day with the normal optimism that I start all projects with – looking for ways to contribute and to absorb as much as is possible about the systems in place, learn everyone’s name, understand the political environment, as well as the culture of the organization. This project was being coded in PHP by other contractors as well as an internal web designer. After a couple of days, it became obvious that there may be a huge learning curve with the app – there was absolutely no usable documentation for the design or the myriad of third-party API’s that were used. To make things worse, the code lacked even the most basic commentary. Things were thrown together, portions of scripts copy and pasted one into/on-top-of another. To add insult to injury, there was no ‘dev’ environment – all code was changed on the production server! Additionally, no QA person/team existed, nor were there any load tests performed on the app.
When designing a high-availability web application, it is crucial to follow basic infrastructure and design principles:
Separate development code and data from the production code and data until it is fully debugged/QA’d and integration tested.
Maintain separate databases for development and production. Preferably, a separate db for QA.
Separate, as much as possible, the presentation layer from the business logic and data layers.
Maintain loose coupling between modules and classes. A change in one object should not require a cascading change in code that does not deal directly with this object.
Document what was done and why.
Knowing this, I began to decipher the application. I had to rely on the team members memory since no documentation existed. It was at this point I discovered a bit of resistance – they would explain the code they produced, not the underlying functional design that was used for the development. I needed the functional design specifications AND the API documentation. ”Just use what is there…” – but the code was amateurish, indecipherable, and unusable! I have never seen so many header redirects in a PHP script that was not designated as a controller for the app as I experienced there! How can one trace a logic error given that level of spawning?
As a starting point to any code creation, I always implement a logging class and error/exception handlers. As you may guess, there wasn’t any function or class used to standardize the error logging/debugging – it was all sent to the screen. I then hunted for the primary Apache logs: no one knew or would share which one was the primary Apache log file (it was not in /var/logs/httpd on CentOS ). I did find error_log and access_log files – but there were multiple instances of them strewn throughout the system.
I began to take simple yet important steps to make the totally procedural application into a segmented one, introducing OO patterns as I went. The first was a singleton logger class. Then I authored a singleton DB class. I was surprized to find that MySQLi was NOT used – the old MySql db lib was. Personally, I now prefer PHP’s SPL PDO since it allows easy translation from database record(s) to object(s).
One of the assignment we had to do asap was to integrate an additional payment gateway. I watched as the designer create another monstrosity; my mouth agape, chin on the floor – cutting and pasting his way through multiple files, using brute force to get it to work.
In the end, the environment was not in line with my principles (easy maintainability, lose coupling, composition over inheritance) or methodology (design, document, THEN code, test, debug, test, load test, debug, update documentation, etc….). There was a chasm between what they do and what I am able to accept – after all, if the app breaks, I will be the one responsible for a) fixing it and b) defending the code-base.
When questioning the environment, I was even told by a top-level person that this was the way they did things – no formal code design or standards implementation – just get it to work any way possible.
An additional problem I saw was PCI compliance. Credit card info was stored on the servers – as a session attribute as well as in a third-party application database. I was “assured that everything was PCI compliant” – however, I was unable to review any documentation on how to maintain that compliance since none existed. This was too much for me to accept.
The lesson I learned were many. During an interview session:
- Ask to see some of the code that is being produced by the present team.
- Request to examine the design and ongoing code documentation.
- Find out how they QA and load test the application.
If two or more of these questions are not addressed, or, you discover gaps between your standards and those employed at the company, you may want to remove yourself from the situation. Unless you are going to be the one who implements coding standards, documentation, and testing. You, as the ‘new’ developer, will be responsible for maintaining (extending, debugging) and scaling the code that was already created.
Have a GREAT Holiday Season!


