04.13.2012
When chatting with various web development groups in New York City, I’ve come to find one of the most commonly asked questions to be, “What do you like, and what do you not-like about PHP?” A few years ago, I felt this question was far too broad to have an effective answer, and more or less shrugged it off as a technical icebreaker. These days I believe it is a very valuable question, in which the answer can not only represent one’s background and experience, but one’s philosophy as an engineer as well. From small-startup media apps meant for viral distribution, to rich social media experiences, to publishing platforms with thousands of concurrents demanding hulky amounts of data in a merciless environment, my experience with PHP based frameworks has given me a deep enough appreciation that I feel defining it as a “scripting language” is a bit incomplete. As for the answer to the question, my response is one in the same – the things I enjoy about PHP are quite often the things I find frustrating!
From the very beginning, strictness has been programmed into my coding habits (pun fully intended). I was introduced to software engineering by way of programming languages such as C, C++, and Java. Writing software in such a way as to have individual functions, routines, components, and scripts protected from all other moving parts became the norm. Code was written to keep each piece “safe” from every other piece, and the possibility for bad input, incorrect datatypes, or other erroneous behavior seemed minimized beyond the initial development phase. The belief was that in exchange for thoroughly abstracted datatypes, more extensive documentation, and extra lines of code to maintain functional integrity and error handling, less time would be spent debugging or with QA, and the risks of a poor user experience in production strongly reduced. The philosophical end goal is to create software that can’t fail, that has the integrity of the human body, in which each system is so well adapted to working in tandem with every other system that only powerful external events could bring it to failure. Perhaps PHP can’t produce software as “perfect” as our own DNA, but if we wish to get to the moon, we should aim for the stars. Without strictness as a priority, this ideal can never be reached.
PHP was easy to pick up very quickly due to its influence from C++. Creating Object Oriented applications in PHP came naturally, and having no prior background in web development, I began using PHP as though it were C or C++. I recall one of the first routines I wrote, which included conversions from strings to integers and integers to booleans, as a function which could accept all three datatypes and produce the same output was incomprehensible. Thankfully my boss found my naivety to be quite amusing, and my introduction to dynamic and weak typing began.
PHP’s flexibility is what makes it great for the web. Escaping and sanitizing aside, having the dexterity to perform comparisons and compute logical conditions on a dynamic range of user input allows web apps to return requested data in a more elegant manner. Many of the PHP core functions’ abilities to accept a wide variety of datatypes not only makes the language more simple to learn and gives new developers more license over how specific tools are used, but allows the massive variety of web apps in our contemporary culture to operate with more freedom and stability. In most cases, incorrect datatypes or flaws in syntax merely result in unexpected data returned from the request, as opposed to the application simply crashing. In fact, serious architectural flaws can even escape unnoticed, and in many cases, bugs can occur without having any noticeable effect on the user experience! This sort of behavior is more suited for the web, where changes to any popular application are frequently made, and concurrent use of the application never ceases.
The freedom from having to enforce strictness to avoid compile time errors seemed like time saved at first, but as my experience grew, my tendency for strictness returned. I still find it is easier to quickly comprehend code from another author, easier to track down and isolate bugs, and easier to plan long term architecture when integrity is programmed into each procedure, with accompanying documentation explaining exactly what input is expected and exactly what output should be returned. Writing software in PHP is something I really do enjoy, but I maintain that a proper engineer will always have sharp criticisms of any system, be it a tool, an application, or a language. The agility and flexibility of PHP can often allow and encourage bad programming practices, especially in consumer oriented environments where time is a scarce resource. Due to my initial education in Computer Science, I feel a philosophical conflict between, “…make it work, then make it secure, then make it elegant,” and the reverse. Forgoing integrity for the sake of time can allow even very talented developers to overlook serious shortcomings in code.
The other day I was working on a long untouched codebase written by a different party for one of our clients. Unintentionally, I came across a classic example of everything I’ve mentioned above, encapsulated in one single line of code. The overall function was saving records of a hierarchy of relational objects, but one of these failed to return errors when I was purposely supplying bad input. The issue was narrowed down to a procedural loop on an array from a webform submission, which was initiated by checking if the array contained data. Encountered here was the use of PHP’s count() function, which can evaluate to “1″ (which, in PHP, is bewilderingly equal to “TRUE”) if the wrong datatype is entered. A few, simple mistaken keystrokes allowed for a logical operand to find its way into the function’s argument as well. The end result was the count() function evaluating against empty arrays and boolean types by using what was interpreted as a string in the argument. More specifically, this argument consisted of a variable assigned the value of FALSE and the aforementioned logical operand. Thus, where $var is assigned a value of “FALSE”,
count($var > 0) { //procedure }
will always evaluate to “1″, and the procedure will be performed, even when not intended. This application ran successfully with this condition being computed thousands of times for months, never experiencing any problems. The resulting procedure caused no exceptions, and the end users submitting the webform never experienced any interruption in their user experience. On one hand, this is a terrible consequence as, in this case, data could be lost without notifying the end user, as well as this bug having the potential to escape notice. On the other hand, PHP allowing $var to be reassigned multiple datatypes, and PHP’s core functions able to return data even with such malformed arguments, allowed no interruption of the application’s services. It is in situations such as this where I state that the things I like about PHP are simultaneously the same things I don’t like. Broken code is bad, but application still performing for end user is good. My tendency for strictness usually causes a bit of “overkill” in checking for types, and I often combine PHP’s is_array() and empty() functions before initiating a loop on a variable which is expected to be a populated array. This allows for potential changes to whichever overall script, class, or procedure is being worked on, and I trust that there isn’t a considerable performance sacrifice in the modern era of computing hardware.
For all the work I’ve done in the decade since my first software application, Im sure I’ve been unwary to similar problems of my own creation, thankfully patched up by the arduous work of my colleagues. PHP’s freedom allows anyone to get away with simple mistakes that lead to big consequences. This same freedom can often allow an engine to chug along without the audience ever noticing. It is hard to determine which of these is the stronger argument, so it all boils down to one’s perspective on each individual situation. The experience for the end user, in the long term, can often be more important than maintaining strictness and integrity in the short term. It is possible that an engineering team of a given web company doesn’t have the freedom decide. Consequently, the typing disciplines of PHP are both what I enjoy and what I find cantankerous about working with PHP frameworks.
Article by Todd M.