* PHP attracts idiots. Partly that's because you don't need to know anything to make simple PHP. So, in the large pool of PHP programmers, there are a ton of idiots. And those idiots produce a lot of verbose code that gets used because it does something. Ruby, Python, Perl, etc. all put up a larger barrier because they don't just come with a session handler or whatnot built in. And that weeds out more of the idiots. Doesn't really have to do with PHP the language, but it is nonetheless significant.
* PHP has a bad type system that leads to errors. There, I said it. The fact that 0 == "string1" and 0 == "string2", but "string1" != "string2" is unacceptably bad.
* PHP has no namespaces. Yeah, they're planned for 5.3, but the implementation is just ugly. This makes it more likely to botch something in a larger project.
* Which leads me to my next point: include/require. In PHP, it's decently common to say require('some_file.php'); and just grab a huge hunk of code. Eww! That code could be doing anything - adding in variables, executing code, etc. While it's true that other languages can do that as well, that's generally not the case - other languages are more in favor of importing objects or functions. Partly it's a language thing, partly it's a culture thing.
* Magic! So, how does mysql_query() know which database to connect to when you don't pass in a database connection? I mean, I'm guessing they're either using a global or if it's in C a static external variable, but PHP is littered with this crap. It's not necessarily bad, but it's magical.
* Functions! So, PHP now has cool object oriented stuff. Still, it doesn't use it at all. I don't object to strlen($var) that much when compared to $var->len(), but there are other cases where it's just crappy. So, PHP has a function strpos() which will return the position of the first occurrence of a substring within a string. Quick! In what order do you put the variables? In this case, it's string to be searched, search string. What about preg_match()? Oh, there you put it in the reverse order! And really, when writing functions, there is no "proper" order, but if you're doing $string.preg_match('/^apple$/'), there's a clear order.
* Looking more at preg_match(). What does it return? It doesn't return a match, it returns a count of the matches it finds. If you want the matches, you need to pass in a variable that it will take a pointer to as an argument so that it can place the matches in there. Bleh! How would this be done in a nice OO-way? $var->preg_match('/^apple$/').count() would get you the count and otherwise you get the match returned. Easy in a way that requires less memorization of weirdness and doesn't feel so wrong. And crappy things like that are done throughout PHP where things are weird, but end up
* php.ini. Terrible idea. PHP allows you to change very important things install-wide, directory-wide, app-wide, ick-wide! It's not just magic quotes. It's more that you never quite know what you're deploying to in a bad way.
Finally, it's that PHP is an older-style language without the cool things that newer languages can do. PHP isn't bad per-se, but it isn't good either. The biggest thing it has going for it is that it's easy on shared hosting. With VPSs coming down in price to the point that they don't represent a huge premium over shared hosting, that's become less of an attraction. PHP is fine, but there's a decent amount to get annoyed with when creating a larger application.
I think the first reason is probably the most significant. A lot of the other things are just warts and pet peeves, but what really got me down working with PHP professionally was the level of code I had to work with. Not only did I end up having to maintain flaming wreckages of code written by people who couldn't even properly be called amateurs, but after doing it for a couple years I found it very hard to improve my craft by seeking out good code to learn from.
I jumped headlong into Rails 4 years ago after having been enamored with Ruby over Perl for sysadmin type scripting and text-munging. Yeah Ruby has some bad warts too (the runtime!), but the quality of code in the community is an order of magnitude better.
Yep - the first is the most significant because of the others.
Which is to say, most people with a clue or with much experience see all the problems with PHP and move onto something else and have no problem doing so. The remainder are those who either can't or won't and a large percentage of them are the "idiots".
Well said. The thing that bothered me the most when I forced myself to use it was that it seemed like a high-school language hack tried to rewrite perl and got some of his buddies to help. Each of these guys hacked in their own versions of standard functions ad-hoc, and they each chose their own naming convention (e.g., strcmp vs str_replace). There is no uniformity in the language. Elegance is completely lacking.
If you're new to programming, don't waste your precious memory to inventorying an ugly mass of built-in PHP functions. Just pick Python, Ruby, C# or something else--anything else. If you have to learn it for your job, well, learn one of the other languages anyway.
>>> PHP attracts idiots. Partly that's because you don't need to know anything to make simple PHP.
Bit harsh. People are not idiots because they haven't studied computer science and don't know their algos from their elbows.
PHP is easy for quick and dirty - primarily business doesn't care how dirty the code is provided it's done quickly and the crashes don't hurt the bottom line too much.
I can't say I love PHP, but some of your criticisms are a little silly.
For example, about typing... your argument is that when you cast a string to an int, it returns 0. What would you have it return, null?
Typing is jank in a number of ways, but in most cases I See the logic in the original decision. To a noice, the idea that false == "false" (because "false" casts to 0) but true != "true" just seems broken. But what else would you have it do?
About namespaces, people are complaining that PHP should use the dot operator like every other language. PHP uses dot for concat, which eliminates the ambiguity of using + for both concat and addition that exists in other languages. Now, they're going to use a backslash for namespace resolution. And that does create operator ambiguity. So PHP trades one ambiguity (dot) for this other.
And what do you possibly mean by "older style language"? Do you mean functional features? As you probably know, lambad's and closures will be available in 5.3. I agree that Python (my language of choice) and even C# (my 2nd fave) seem cleaner. But of course they do. They're new. Java seemed clean in 1997, too.
And finally.. I do value consistency in userland code and in the runtime. And PHP is horribly inconsistent. A salvation army of a language. But that stopped actually affecting me about 8 years ago when I left behind VIM for a real IDE with intellisense.
I wouldn't have it return anything. I'd have it throw an exception (type error). Dynamic typing can be a Good Thing. Pretending types don't exist is probably a mistake.
PHP uses the backslash for escaping characters in strings and for line continuation. There's ambiguity being created any way you look at it.
Many languages much older than PHP seem much more modern. Scheme, Smalltalk, Haskell, Python and even Perl come to mind.
Well, to be fair, most programming languages don't have this problem so it isn't actually that hard to overcome. The problem is that PHP attempts to automatically re-cast variables to different type. So, you try to do int(0) == str("apple") and it says "hmm, we have different types here, but if I made them the same type, maybe they'd be equal. Well, strings should just be integer 0 and int(0) == int(0) so that makes true, right?"
Most languages won't automatically re-cast variables. In PHP, "0" == 0 and "1" == 1. In most languages, they are not equal because they are different types. PHP's auto re-cast gets you into a lot of trouble. What would I have it do? Not auto-recast things to different types. I wouldn't call it a silly criticism seeing as though Java, Python, Ruby, C# and I'm sure others lean my direction rather than PHP's direction.
I agree that Python (my language of choice) and even C# (my 2nd fave) seem cleaner. But of course they do. They're new.
Um, Python came on the scene in 1991. PHP's from 1995.
The reason I'd call PHP an "old style language" is that, while it may have new features, many of those new features are poorly implemented in a way that shows a lack of understanding of the value of those features and that none of PHP's library uses those features.
Strings are still primitive data types in PHP. Since strings are primitive data types and not objects in PHP, you can't have the little nice things that you get in ruby, python, java, c# without resorting to functions that take the string as a parameter. $string->match('/pattern/') is much nicer than match($string, '/pattern/') simply because you don't need to memorize the order the arguments are passed in. And, as I pointed out, PHP isn't even consistent about it. Sure, you can say that PHP has OO-capabilities, but it doesn't use them in the library which means that all the library stuff you'd do doesn't leverage any of that. PHP also doesn't support multiple-inheritance or mixins which makes OO a lot less useful.
PHP has added new stuff, but it's just not all that useful because everything is old stuff and most PHP programmers wouldn't know the difference between a reference and a copy even to have an opinion on it. Other languages are a lot nicer to use not just because of features, but because you actually get to use those features with the language's and library's built-ins.
It's not that PHP is terrible or anything. It's that it was originally meant for things that didn't require complexity. When people wanted to use it for more complex things, it seems like they said "object orientation, that does complexity" and didn't really know what the term meant or why it was useful when they implemented it. Part of it might be not wanting to break backward compatibility and so one can argue that those who originally created the language made a crappy tool and now the current people have to keep that all alive while other languages were designed better from the start.
And the real question is, what does PHP offer to overcome this crap? And it really doesn't offer (at least me) anything. I'm not going to be using a shared host and so PHP's run-anywhere-ness doesn't help me. Other than that, I can't see a reason to run PHP over a nicer language. It's not that PHP is so terrible. To be a bit of a troll here, PHP's like Windows 95. Awesome when it came out, but now it just looks old. When PHP4 was the in-thing, it was easy to cook up a hack-ish script and get it running on any shared host. Now, other languages have great libraries, much better deployment options, and just a nicer coding experience. I remember the time before other languages took the web seriously. PHP rocked then. It offered everything you needed to make a little web app with built-in functions. And other languages wanted me to jump through all sorts of hoops to do simple things like sessions. PHP was like a language and framework in one. The problem is that people coding in other languages started beating PHP at its own game. Making their frameworks better than what PHP offered and better than what PHP + PHP frameworks offered. And so PHP lost a lot of its appeal as things like mysql_query() and $_SESSION and $_REQUEST no longer held the awesome value that they did in the days of yore.
It's not that PHP's terrible, it's that the other languages have made up their ground and PHP hasn't in the areas that it was weak - it may have added features, but it never integrated them into the language and library and so it just seems old.
A good list, but I just have to add one which is a killer for any good app:
PHP has terrible unicode support. Almost uniformly every app that starts out using the default PHP function set ends up failing horribly when data with non-european (or even just non-ascii) characters end up in it. There are a whole lot of kludge workarounds, but they're basically an admission of defeat rather than a real statement of support.
* PHP attracts idiots. Partly that's because you don't need to know anything to make simple PHP. So, in the large pool of PHP programmers, there are a ton of idiots. And those idiots produce a lot of verbose code that gets used because it does something. Ruby, Python, Perl, etc. all put up a larger barrier because they don't just come with a session handler or whatnot built in. And that weeds out more of the idiots. Doesn't really have to do with PHP the language, but it is nonetheless significant.
* PHP has a bad type system that leads to errors. There, I said it. The fact that 0 == "string1" and 0 == "string2", but "string1" != "string2" is unacceptably bad.
* PHP has no namespaces. Yeah, they're planned for 5.3, but the implementation is just ugly. This makes it more likely to botch something in a larger project.
* Which leads me to my next point: include/require. In PHP, it's decently common to say require('some_file.php'); and just grab a huge hunk of code. Eww! That code could be doing anything - adding in variables, executing code, etc. While it's true that other languages can do that as well, that's generally not the case - other languages are more in favor of importing objects or functions. Partly it's a language thing, partly it's a culture thing.
* Magic! So, how does mysql_query() know which database to connect to when you don't pass in a database connection? I mean, I'm guessing they're either using a global or if it's in C a static external variable, but PHP is littered with this crap. It's not necessarily bad, but it's magical.
* Functions! So, PHP now has cool object oriented stuff. Still, it doesn't use it at all. I don't object to strlen($var) that much when compared to $var->len(), but there are other cases where it's just crappy. So, PHP has a function strpos() which will return the position of the first occurrence of a substring within a string. Quick! In what order do you put the variables? In this case, it's string to be searched, search string. What about preg_match()? Oh, there you put it in the reverse order! And really, when writing functions, there is no "proper" order, but if you're doing $string.preg_match('/^apple$/'), there's a clear order.
* Looking more at preg_match(). What does it return? It doesn't return a match, it returns a count of the matches it finds. If you want the matches, you need to pass in a variable that it will take a pointer to as an argument so that it can place the matches in there. Bleh! How would this be done in a nice OO-way? $var->preg_match('/^apple$/').count() would get you the count and otherwise you get the match returned. Easy in a way that requires less memorization of weirdness and doesn't feel so wrong. And crappy things like that are done throughout PHP where things are weird, but end up
* php.ini. Terrible idea. PHP allows you to change very important things install-wide, directory-wide, app-wide, ick-wide! It's not just magic quotes. It's more that you never quite know what you're deploying to in a bad way.
Finally, it's that PHP is an older-style language without the cool things that newer languages can do. PHP isn't bad per-se, but it isn't good either. The biggest thing it has going for it is that it's easy on shared hosting. With VPSs coming down in price to the point that they don't represent a huge premium over shared hosting, that's become less of an attraction. PHP is fine, but there's a decent amount to get annoyed with when creating a larger application.