Two More Reasons to Not Use PHP

In a recent project, I found a couple more reasons to dislike PHP (not that there aren’t plenty already). While, admittedly, PHP 5 is a substantially better language than PHP 4 (for instance, it kinda supports object-oriented programming), it’s nonsense like this that makes it nastier to work with than better-designed programming languages.

  • Quasi-signed Integers

    According to the documentation, PHP “does not support unsigned integers”. Like many things in PHP, it’s true, except when it’s not. Obviously there’s an expectation that integers will be treated as unsigned values, since functions like sprintf() include provisions for handling them. I stumbled across this when using the ip2long() function. It always returns an integer for the IP address, even though it may be negative if your integers are 32 bits long! I ended up having to wrap every use of the function with a clever but nasty hack to avoid storing negative IP addresses in the database.

    The “proper” behavior for dealing with values larger than the integer type can handle, according to the docs, is to promote it to a float. That might be reasonable if it were consistent…but it’s not. For instance, if you’re on a 32-bit platform, you’ll probably find that 0x7fffffff is equal to 0x1000000000, because hex values don’t get promoted consistently. Going the other direction isn’t any better. If you cast 2147483648 on a 32-bit system to an int, it comes back as -2147483648, without so much as a warning. In general, integer math in PHP is risky.

  • Bizarre NULL semantics

    PHP has a NULL type. What it doesn’t appear to have are any rules, conventions, or even vague notions about how to handle it. In general, I’d expect one of two results if I use a NULL value in a computation or pass it to a function that doesn’t have obvious NULL semantics (e.g., is_null()):

    1. A returned NULL value, à la SQL. If I try to do a computation with a missing value, I get no value as a result.
    2. An error. Python, for instance, will throw exceptions if you try to evaluate something like “1 + None”.

    What does PHP do? …who knows?. “1 + NULL” is 1, “ip2long(NULL)” is -1, and “NULL + NULL” is NULL. Nothing In, Garbage Out.

    While this may sound niggling, keep in mind that PHP’s stereotypical use is database-driven web apps, and SQL-speaking databases all support NULL values. You generally don’t want to handle NULL in the same way that you handle a value that’s present, and you certainly don’t want to handle it in an arbitrary and indeterminate fashion. This caused much consternation on my aforementioned project, as NULLs were “helpfully” converted to zeros and saved into a column in the database which had a UNIQUE constraint on it. It worked okay for the first person save the form without filling out that value…

Update:I got flak on Reddit for posting an X sucks article, which is probably fair. I added a comment there finishing my thought, which I hope will turn it into X sucks, here are better alternatives.

These are indicative of fundamental problems with way the language is developed; namely, the apparent lack of any consistency or thought regarding the consequences of the designers’ decisions. I’ve had an app crash during minor-version PHP upgrades because they changed the semantics of one of the LDAP functions and didn’t note it in the changelog. I’ve fought with data-input bugs in existing PHP apps that invariably crop up because somewhere, someone didn’t wrap a request variable with the four lines required to un-magic-quote-it, or un-magic-quoted a variable on a system where it wasn’t turned on. And it took them until version 4.2 to realize that it was maybe a bad idea to, by default, allow web requests to set arbitrary variables in the global namespace.

Why fix PHP when, as I noted in the post, there are already plenty of other languages that don’t suck? Python’s well-thought out and has an enormous set of libraries and development frameworks available for free. The same can be said for Java. (I personally find the repetition it often requires maddening, but at least it’s consistent.) I haven’t played with it myself, but lots of folks back Ruby too, and Perl’s still got a sizable fanbase. The changes required to make PHP enterprise-ready are immense:

  • audit all functions to ensure proper handling of NULLs
  • completely redo how integers are handled
  • modify all functions to throw exceptions when exceptional cases occur, rather than returning 0/FALSE/-1/”ERROR”
  • cull unnecessary nearly duplicate functions
  • standardize function naming
  • introduce namespaces

…and that’s just what I’m coming up with off the top of my head. Why bother fixing something so fundamentally broken when better things are already out there? (To be fair, I know that PHP 6 is going to try to resolve some of these issues, but that’s going to be a hard transition that’s going to break most existing PHP 5 apps, and it’s still a ways down the road.)

Update, 19 June 2017: I got a note from Craig B. Peck at iFlexion with an article they posted on the resilience of PHP. I can’t say that the problems generated by its use are the ones that I’d want to spend my time solving, but I can certainly believe that there will be plenty of them to work on for years to come for those who are so inclined.

Leave a Reply