The biggest problem with PHP isn't anything built into the language itself, but rather the culture of mediocrity/naivety surrounding it.
As at least one other commenter has said, there are disciplined and skilled PHP programmers. If only they were the majority! Sadly, for the PHP ecosystem, a few good apples don't unspoil the bunch.
Here are a few ways PHP's bad culture manifests itself.
1. Cargo culting
The web is filled with questionable recipes for doing this or that in PHP. I've observed a strong tendency of PHP programmers to approach every possible addition of functionality like this: 1) Google search; 2) find source code that supposedly does what's needed; 3) paste that source code in without understanding it or thoughtfully evaluating its appropriateness.
I'm all for learning by reading other people's code. I'm even OK with pasting code when you understand it fully. But cargo culting is bad, and it seems rampant in the PHP world.
PHP applications often lack a coherent architecture. It's a typical mistake of new programmers--one that I made many times--to think just enough about architecture to accomplish the task immediately at hand. Naturally, this comes back to bite you when you want to extend your code's capabilities. I see this all the time in PHP applications.
Consider Wordpress. Its API is a random, ad-hoc mess of global functions. Things that should logically be exposed as objects aren't (like posts, for example). The API for retrieving content is different depending on whether you're in the mysterious "Loop" or not. And so on. A more detailed analysis of the lack of architecture in Wordpress can be found here:
Similar to cargo culting, Frankenstein coding is when you cobble together an application from a bunch of off-the-shelf plugins or modules. This is a common practice in the Drupal world specifically, but it applies to a greater or lesser extent in much of the PHP ecosystem.
There are two major problems with this approach. First, the chunks of functionality you download are not likely to match your needs perfectly, so you're forced to make due with software that's almost what you want. Second, the code quality of these modules is often abysmal, and that means security flaws, among other problems.
Sadly, many PHP developers seem perfectly content with this. Even worse, they do this for clients, who get a semi-functional end product at bargain basement prices. That practice gives me a cheap, sleezy vibe, and it doesn't help my impression of the overall PHP ecosystem.
The language itself is so-so in my opinion--not good enough to be my go-to language, but not so terrible I'd refuse to work with it. But somehow, probably due to the language's accessibility, the PHP ecosystem seems to have been swamped by coders who know just enough to get by. And that's my real problem with PHP.
I can't disagree with much of what you said. However, you are being too critical of Drupal.
"the chunks of functionality you download are not likely to match your needs perfectly, so you're forced to make due with software that's almost what you want"
Drupal starts you off with 80% of the product functionally complete (!), for free, and leaves you with the spit and polish jar to squeak out the other 20. I find that this 80/20 rule is true for even very complex products. The lazy developer will never do that remaining 20%; this says nothing about Drupal.
You can name a function according to a convention and reach into any part of Drupal, or a contributed module, to pull that specific string that you need. I'll be blasphemous and say that not having to instantiate half a dozen objects just to dive through their properties to achieve the same result -- as you would likely have to in a "proper," purely OO CMS -- is very refreshing. The result is the same and the code is readable.
"Code quality is often abysmal."
True for one out of ten new modules that I encounter; and you are free not to use those modules. The heavy weights: CCK, Views, etc. are excellent.
"Drupal starts you off with 80% of the product functionally complete (!), for free, and leaves you with the spit and polish jar to squeak out the other 20. I find that this 80/20 rule is true for even very complex products. The lazy developer will never do that remaining 20%; this says nothing about Drupal."
I agree with that statement 100%. I don't think Drupal forces you to build a half-finished site with ten security holes. My problem is that lots of people do anyway. I don't necessarily blame Drupal for this phenomenon. I just think it's emblematic of a culture of quick and dirty coding that ultimately makes life harder for professionals and our clients.
As a programmer who deals with wordpress on a daily basis I feel like I have a different view to it's inner workings. The simple functions for the_loop(), the_title(), and the_content() are things i rarely touch, as they are more template functions for displaying templates. There is a reply to The post that describes using "do_action" which depending on what you want would be a better option for achieving the formatted post content.
However, I have a real love/hate relationship with wordpress plugins. Writing plugins is very easy, and there is sufficient documentation within wordpress itself to describe most functions. However, there are a LOT of plugins I've come across that are written terribly. I would love to express my dislike of them, however I've taken on the "If you cant write better, then don't criticize" mentality.
Maybe one day I'll feel confident enough in my skills as a coder to name and shame these scripts, but for now I'm concentrating on becoming a better developer, and writing good PHP.
I agree that the Loop can be convenient at times. But I still contend it's bad architecture--just as many seemingly convenient programming practices are.
The loop functions operate on (global) variables that are not explicitly passed into them. Therefore, without consulting their source, one cannot know what data they're touching. It's not obvious how and when these global variables get set and modified (which is one of the classic reasons global variables are considered Evil). Presumably, the variable are are set by the_loop(), but the opacity here is bad style.
On top of that, the fact that you must have these globals set to use the Loop's formatting functions makes it much less practical to use them in novel ways--i.e. in contexts other than the Loop. Sure, if you want that same data somewhere other than the Loop, there are other functions you can use. This is the typical reply I've heard in defense of the Loop. But that's a fairly poor defense: It's admitting that the API is so wonky, the WP devs had to create a bevy of functions that all do roughly the same thing to patch over each other's weaknesses. Why should there be a different way to get some post data in the main content area versus anywhere else?
BTW, I'm not just nit-picking Wordpress about the Loop. I'm talking about it because it's a well-known and very illustrative example of what I perceive to be a broader pattern of poor architecture throughout Wordpress.
> the culture of mediocrity/naivety surrounding it
Unfortunately there is also a counter-culture of elitism and condescension. I'm constantly encountering PHP devs who look down their nose at their fellow developers and assume that anyone who doesn't write sites exactly the same way they do is ignorant and full of failure.
That's the feeling I took from the article. The author _knows_ all the best practices, but sometimes he just wants to get shit done and PHP lets him do it.
I don't think there's one right way to code a website. So I wouldn't look down my nose at someone who uses a perfectly good architecture that's merely different from the one I would have chosen.
That being said, there is such a thing as a wrong architecture. (And for non-trivial projects, the absence of architecture is clearly wrong as well.) The choice between several good designs is partly subjective, but some designs are objectively bad. So I think criticism (not condescension) is warranted at times. Wordpress being a good example.