Why PHP Sucks

“Recalling the exact syntax for the built-in stab() function, you make a sane assumption and call shoot(GUN, FOOT); The foot shoots your gun.”
— Some user who calls theirself “plams” on the Something Awful Forums

This is a list of reasons I don't like PHP.

Some reasons involve actual deficiencies in PHP; others involve features that other programming languages provide that PHP has no reason not to provide.

When I speak of "other languages", I'm thinking primarily Perl, Ruby, and Python1, that sort of thing.

Common Arguments In Favor of PHP

“PHP is easy to deploy.”

True, but once you select a programming language and templating system, getting it installed on a system shouldn't take any more than an hour. And I'm including worst-case scenarios here.

And this is a one-time operation. If you have to do it on a few hundred machines, it can easily be automated. When hundreds if not thousands of man-hours are going to be spent doing actual coding, is the time you spent installing a programming language and templating system really an issue?

“PHP is easier to pick up than Perl/Python/Ruby/etc.”

Picking up the basics of just about any language isn't that hard. Picking up proper coding practices that promote maintainability, security, simplicity, resiliency, etc. in any language requires time and experience. Most coders who have this kind of experience will have no problem picking up a new language. Most coders who don't have this kind of experience will write crappy code for a while, no matter what language they use.

One thing about PHP's documentation. It's incomplete. User-provided comments in the online documentation are frequently inaccurate. Arguably, this actually hinders one's ability to learn how to write proper PHP.

“More people know PHP than Perl/Python/Ruby/etc.”

This is probably true, but do more good programmers know PHP than Perl/Python/Ruby/etc.? If they can't pick up other languages, do you really want to hire them?

“PHP makes it easy to build web sites!” a/k/a “PHP provides templating and embedding of code with HTML built-in!”

This is arguably true, but systems that provide templating and embedding of code in HTML exist for other languages.

It's just that PHP is the only one that provides such a system built-in.

There are many based on Perl. I'd choose Mason, but there are Template Toolkit, and millions more.

For Python there is Spyce.

Specific Reasons Why Other Languages Are Better Than PHP

Invoking external programs

In Perl, for example, there are two ways to use the system() call, which executes an external program. The single-argument form:

# contrived example, I know.
system("/usr/bin/svn commit -m \"" .
       some_quoting_function($message) . "\"");

And the multi-argument form:

system("/usr/bin/svn", "commit", "-m", $message);

The multi-argument form is preferred practice for the following reasons:

  • It's a better security practice when dealing with user-supplied data. It's impossible to construct a string that will full Perl into passing multiple arguments this way.
  • The single-argument form requires string escaping. If portability across Unix and Windows is required, you can't use the same string-escape function. The multi-argumet form requires no string escaping.
  • In most cases, the single-argument system() invokes an additional process for the shell, incurring a potential performance penalty. The multi-argument form does not.
  • And you're typing less code and it's clearer.

Unfortunately, PHP does not provide a multi-argument form for any of its built-in functions for invoking external programs. The exec, passthru, proc_open, and system functions take just one string to specify the command and its arguments.

Higher-Order Programming

UPDATE: Well, butter my butt and call me a biscuit. PHP 5.3 will natively support closures. This should have been listed first because it was only my most major problem with PHP.

In higher-order programming, functions can be treated as data. They can be assigned to variables; they can be passed as function arguments; they can be the return values of functions. You can create functions that do not have names, typically known as "lambda functions".

PHP's form of higher-order programming is known in PHP circles as "callbacks" or "function handling functions". The syntax is a joke compared to other languages.

When using create_function, you're passing a string. This is a bad security practice if that string contains external data of any kind; additional caution must be exercised. Also, your text editor will probably not syntax-highlight it or auto-indent it for you, like it would with languages that implemented lambda functions natively. Also, in some more complex cases string-escaping will be necessary.

When referring to other functions, you're passing a function name instead of an actual function reference, incurring a potential performance penalty.

PHP does not support closures. There exist hacks that involve passing a bunch of code around in a string, though. But still, closures are more elegant in languages that implement them natively.

Other Issues

In PHP, the names of built-in functions are inconsistent. Is it isset() or is_set()? Is it isnull() or is_null()? Is it sort() or array_sort()? Is it merge() or array_merge()? Even I don't remember. I have to look up the PHP documentation to answer these. I'll let you do the same.

The arguments to built-in functions are inconsistent.

The built-in functions' return values are inconsistent.

The number of built-in functions is too large. Do we really need 11 sort functions (scroll down)?

Function names are case-insensitive, but variable names are case-sensitive. WHY?

As I've stated above, the vast majority of official and user-contributed documentation is poor.

PHP's authors have made a few non-backward-compatible changes to the language. Not just between PHP4 and PHP5, but in minor point releases of PHP4.

Magic Quotes

There is also the fact that PHP ever had the magic_quotes feature in the first place. While it's been turned off by default for quite some time, and will be removed from PHP 6, it will still affect you for some time to come in the following situations:

  1. When writing programs to distribute to other people who may be running PHP4 or PHP5. Such as yet another forum or CRM package.
  2. When writing programs you may port from one operating system to another someday. Even if both are running the same version of PHP...

...You see, there's one particular PHP feature called magic_quotes_gpc, where things get "interesting". It is on by default in PHP4. It is off by default in PHP5 on certain Linux distributions; on in others. You can probably stick "php_flag magic_quotes_gpc" off in apache.conf or .htaccess. But some shared-hosting providers make this impossible. In the worst case, you may very well have to pollute your code with things like this. (There are common techniques such as ereg_replace("/\\/", "") that a lot of programmers use, which do not work right in all cases.)

If You Must Use PHP

Advanced PHP Programming by George Schlossnagle should be required reading.

When doing database programming, learn how to use prepared statements. It will make your code more secure, and you will soon discover that you are much happier. Chances are, you will need to use an abstraction layer such as PEAR Database or ADOdb or PHP Data Objects. PHP5's mysqli_* functions also support prepared statements, but there is almost never a reason to use RDBMS-specific functions.

Start using a templating engine. Use it to separate your business logic from your presentation. You will discover that you are happier when you do this. For most projects, you don't need a large package like Smarty. This public-domain system in 40 lines of PHP code will do you just fine.

Other Anti-PHP Sites

Footnotes

1 Python does have some rather silly limitations on lambda functions. Namely, that they can only take up one line, and that they must contain only a single expression, not a series of statements. Supposedly, nested functions and list comprehensions help, but I haven't much experience with Python, nor with list comprehensions in any language.