That Faltzer Ain't One of Ours

If wishes grew on trees, then life would be a breeze.
  • Why PHP sucks

    Posted on 2009-07-27 00:00:00-05:00 Faltzer 10 Comments

    I've always hated PHP, ever since that day where I had to learn the language to make rough modifications to phpBB 2. I had only known Perl and Ruby back then, and I learned Python a year later, and they proved to be leagues better than PHP, no ifs or buts. Whenever I am attempting to debate the quality of PHP, I'm always treated with the same old, tired arguments that look more like bad attempts at covering the fuck ups the language has made instead of actually explaining how they aren't fuck-ups or admitting that they are. The most that can be summarized is that typical "PHP takes patience to get the hang of, just like every other language. It's actually very good and straight forward, no excessive complicating involved" excuse. That's bullshit. Like many articles out there degrading PHP for the terrible language that it is, I too will give some common and my own reasons as to why PHP sucks, and why I hate it.

    There are so many built-in functions that the reference has been changed from a flat list to one-hundred eighty categories of functions. There are at least 22 functions alone for finding something in a string, depending on if you want to be case insensitive, if you want to replace that something, if you want to search from the end first, etc etc... some of those functions also have flags, which is a bit self-defeating. The reflectiveness API looks absolutely nothing like the rest of the language and actually more closely resembles a failed attempt at wedging Java into C. The developers can't even decide whether or not they want underscores in function names or not. is_object vs isset? base64_encode vs urlencode? str_rot13 vs strpos? Straightforward indeed.

    To the best of my knowledge, the built-in database access functions don't use or even allow the use of variable binding, which is possibly why I hear about so many common PHP applications with SQL injection exploits. There are, of course, several different ways to get around this, including a flag in a config file that affects every script on the whole server, impairing everybody else, and a function named mysql_real_escape_string. (I eagerly await the announcement of mysql_fake_escape_string.) There are also dbx_escape_string, escapeshellarg, escapeshellcmd, pg_escape_bytea, pg_escape_string, pg_unescape_bytea, addslashes, addcslashes, preg_quote, quotemeta, mysql_escape_string, mysqli_real_escape_string, and sqlite_escape_string. Why? Who knows? Perl’s DBI extremely strongly discourages ever inserting user input directly into a SQL query; even if the RDBMS doesn’t support prepared statements, DBI will fake them for you. SQL injection is thus impossible. I don’t know why you PHP guys haven’t been using mysqli; this is an absolutely trivial problem that was solved years ago, yet I keep seeing more and more convoluted hacks to emulate functionality built into both PHP and MySQL. Of course, Perl, Ruby, and Python are all big on ORMs lately, and there are at least a couple solid ones for each language. To add insult to injury, there's both MySQL and MySQLi for PHP.

    Arrays and hashes, despite being completely different, are merged into the same data structure because I guess it would just be hard to expect new programmers to tell the difference. Teaching by removing difficult details; what a concept. Does PHP even have namespaces or closures yet? I don't think so, really. Oh wait, yeah, I forgot I meant "classes." Silly me; I forgot that \\ for namespaces was a good idea. I'm also not a fan of having the same operators for numeric and string operations either, but almost everyone does that. Python blocks take LESS time and space by definition, since you don't need a line with a lone brace on it at the end of a block. Ruby just uses a keyword to end a block that otherwise looks the same as it would in Python, and uses braces for closures.

    Bad programs do not a bad language make, but there have to be some criteria for a bad language, and I'm pretty sure these should all be on the list. PHP started out as a quick templating language for non-programmers, and it's still not very good for anything better than that. I could write a symbolic algebra package in Malbolge, but that doesn't make it a good idea. PHP is a horrible language for a new programmer and a pathetic language for a seasoned programmer. If you want a decent language also aimed for beginners, use Python. If you want a powerful language with vaguely-consistent syntax and lots of easy-to-use libraries, use Perl or Python or Ruby. If you want to put a cute little counter in otherwise-static HTML, use PHP.

    PHP's map() doesn't even allow for inlining as far as I know (anonymous functions are just too complicated?). Sorting is ridiculous; I count twelve different sort functions, several of which exist only to work around the array/hash hack (and none of which, of course, have the array_ prefix that the most common array functions have). Searching a string is still thoroughly ridiculous. Database access... who even knows, it's different for every database. It's almost as if nobody except Zend knows how to write PHP modules, and since all this stuff is built in everyone else is rather discouraged from trying to write anything better.

    These and these and these and these and these. What do they have to do with Web development? Oh but right, you can choose to just not compile them in, if you happen to be the administrator of the machine you're on and want to remove them from everyone else who may dream up a reason to use them.

    PHP's very poor in regards to modularity, and Python, Perl, and Ruby all have ridiculously huge libraries available with modules contributed from users who actually want to give people an incentive to reuse good code and allowing people to extend and build up on it as an accepted solution (to not reinvent the wheel, but it seems PHP does the very opposite). To add insult to injury, PHP's MySQL extension, which is used ever-so-often, is set to not compile by default. Again, if you happen to be the administrator of the machine, you have to recompile PHP again, applying the same fucking flags you did before just to add DB support. It is trivial to connect to a database with any of them. With Python it's just a simple `easy_install mysql-python`, granted that you have setuptools Python extension installed. Perl/Ruby both have DBI modules which are easy to get and install as well. For PHP it isn't. They haven't even mustered the concept of modularity, and instead think that bullshit like PEAR/PECL is going to fix what should have been in the language from the very beginning. Oh, but sure, modularity and dynamic loading is for nerds!

    We could all write our Web applications in C or even assembler, but for some strange reason we don't. PHP has inconsistent syntax, far too many functions that do almost the same thing, weird scoping rules, and far too much old junk lurking around. It almost seems deliberately designed to encourage obfuscation and require having a manual open at all times. Any of the more commonly-used features in one of the four P's can be duplicated in C with some library or other. Granted, something like Catalyst or Ruby on Rails would be a wee bit more difficult to do, but I don't think we're really talking on that level.

    Speaking of frameworks, I have yet to see one that is not some wannabe Ruby on Rails knock-off. Most of what I see are mock-ups trying to reinvent the wheel when there are other, (while still sub par, accepted) "solutions". To shift away from the topic of frameworks, this is also a problem with PHP in the community as well: Every Tom, Dick and Hary is off making their own implementation of x software instead of improving the already existing and accepted y software. The community is built on separation; nobody is working together; it's everyone going off on their own path, building shoddy piece of software, which again, contributes to spaghetti code lying all over the place.

    Yes, it's a matter of preference of what to use, but it's a preference that leads to ugly code all over the place and a lot of "programmers" raised on PHP who think they rock for being able to make counters but can't really do anything else. As a developer, I do happen to care about what goes on under the hood; I care about code reuse and modularity and clean code and such, because it makes the world a better place. As a developer I do occasionally have to poke around this code other people have created and am treated to messy code written in a messy language by people who think this is normal. It also leads to a lot of jobs I might otherwise want to take revolving around the language, so you can see where that ends up. The language seriously seems to either train or attract the bottom of the barrel and thus coats the Internet with lots of scripts that can only be described as analogous to <marquee>. At least the other languages have communities and documentation that tries to teach people how to code. I have this thing about people using crappy tools, as some may have noticed.

    Comments

    Brandon Evans

    If you are consistent with the functions you use, it should not be as big a deal as you made it out to be. strpos makes a lot more sense than strstr, so ignore the latter. Speaking of this, you mention string searching to be ridiculous. Out of all the things you mentioned here, that's the one I can't agree with for a second. SUIT uses it quite often, and I have had no problems with it. If you do have a problem with it, I'd like to know what it is. In regards to sorting, if you don't like their methods, create your own with usort. Sure, it's bloated, has way more than it needs, but that's because they didn't want to break old scripts with an upgrade by removing them. If you just ignore all of the dated functions, PHP does not seem nearly as messy. The only thing I disagree with is that if they have so many clones, pick one, and in the docs, redirect all the old ones to that one, so they know which one is standard.

    Faltzer

    If you are consistent with the functions you use, it should not be as big a deal as you made it out to be.

    The language is written in a way that encourages just about every new breed to use the inconsistent functions that are built-in. strpos() makes more sense than strstr(), but who is there to tell them that? The interpreter won't tell you that the function you're using has a shitty naming scheme, nor will #php when you ask them for a function for finding the first occurrence of a string. They'll just give you "what works", which is a bad policy, which clearly shows no attempt to promote or even standardize good coding behaviour to give users an incentive to use cleaner code.

    Speaking of this, you mention string searching to be ridiculous. Out of all the things you mentioned here, that’s the one I can’t agree with for a second. SUIT uses it quite often, and I have had no problems with it. If you do have a problem with it, I’d like to know what it is.

    There are a zillion functions to do it; PHP is full of duplicated but slightly different functions rather than encouraging putting pieces together.

    Here's a chart, if you for some reason don't believe me: http://www.tnx.nl/php.html#args

    In regards to sorting, if you don’t like their methods, create your own with usort.

    It is as likely as this...

    Sure, it’s bloated, has way more than it needs, but that’s because they didn’t want to break old scripts with an upgrade by removing them.

    If they hadn't made the language garbage in the first place there wouldn't be so much to fix. With the lack of namespaces, it makes for a giant mess. They just introduced namespaces, but those don't help now. There are already well over 3000 possible global functions, and they will never be categorized in any reasonable manner because durp-you guessed it: backwards compatibility.

    If you just ignore all of the dated functions, PHP does not seem nearly as messy. The only thing I disagree with is that if they have so many clones, pick one, and in the docs, redirect all the old ones to that one, so they know which one is standard.

    They won't; the developers are morons. They hail backwards compatibility above the cleanliness of their own language; they refuse to implement useful features because it would "make messy code" (?!); their choice of a namespace separator speaks volumes. I know people who've worked on the PHP interpreter and they all say that's a god awful mess too. PHP is a shoddy copy of Perl crammed into C syntax. To fix it they would have to turn it back into Perl, and I might as well just use Perl.

    Brandon Evans

    There are a zillion functions to do it; PHP is full of duplicated but slightly different functions rather than encouraging putting pieces together.

    stripos can really do everything the other functions do.

    No arguments with the developers being stupid with backwards compatibility. I do believe C syntax is the best to work with, I believe hashes and arrays should be combined, and I honestly do not know much of anything about namespaces. I create my scripts in whatever is most popular. I know PHP's flaws, and I'm not calling it a miracle language, but I figure there is a lot future languages can learn from it. Without their function clutter, I like it, and if they are not going to fix it, then someone is going to create a next gen language with the same concepts but less clutter, and then we'll have something.

    Faltzer

    stripos can really do everything the other functions do.

    I'm talking about the <em>design</em> of the language, not the functionality.

    I believe hashes and arrays should be combined

    Arrays and hashes are both bunches of pigeon holes where you can store values. The difference is how you get at any particular pigeon hole and their purpose.

    Take Perl, for example. For a hash each pigeon hole has a label and you access the pigeon hole by whatever is written on the label. I understand that PHP only has labeled pigeon holes (hashes), but of course if you label them with a sequence of numbers from 0 to n - 1 the effect is somewhat like using an array (but less efficient in various ways).

    Perl hashes are good for storing things you want to get at by name and where order is unimportant. They are an excellent choice where you need to determine if you already have an entry of a particular name already which often makes them the tool of choice when you need to look stuff up frequently.

    Perl arrays are fairly efficient for implementing things like stacks and queues using push, pop, shift and unshift. They are also easy to access from either end - $array[-1] is the last element of a (non-empty) array for example. They are good for storing things where the order is important. Arrays are a poor choice if you need to search.

    In short: An array is a list of ordered items, useful when the ordering is important. A hash is a set of key/value pairs of unordered items, useful when you want to quickly get from a key to its corresponding value no matter how large the data set might get. Hashes are for mapping, arrays are for ordering. Separation of the two is much more efficient, and it's done on every other respectable language. Just because PHP wants to challenge and change how this is handled does not make it a good idea at all.

    I know PHP’s flaws, and I’m not calling it a miracle language, but I figure there is a lot future languages can learn from it.

    Do tell, what can other languages learn about it? Do you mean they should all run "import cgi" for you?

    Without their function clutter, I like it, and if they are not going to fix it, then someone is going to create a next gen language with the same concepts but less clutter, and then we’ll have something.

    Why wait for another reinvention of the wheel? Just use Perl; it's much more efficient than PHP, and it applies everything that PHP has as a short-coming but much better. PHP is, like I said before, a ripoff of Perl with C-styled syntax filled with clutter. It's not much more than that.

    SM

    I DO find these PHP flaws, the naming of the built-in functions annoyed me.

    The compatibility between versions is one problem.

    SM

    PHP needs a revolution.

    Electron

    I understand where the anger at PHP is coming from, and it doesn't take a computer scientist to notice the poor language design. I'm not sure how people writing endless walls of text about how shitty the internals are is going to help anyone switch to a better, cleaner language. Anyone knowledgeable enough on the subject to understand a lot of the points you've mentioned probably isn't the one using PHP if he or she can avoid it. I reckon the "Why you should be using Python/Ruby" approach is more effective in converting people than the "Why PHP sucks" mindset. I've tried both, and have reached that conclusion.

    I've read a lot of PHP sucks articles in my time, and this one has unnervingly familiar strings in it that I've definitely read before. Hm. Well, Faltzer, at least the facts are straight, except PHP does have namespaces now. And you really don't want closures because they'll be as ugly as hell (create_function alone is already amazingly cumbersome and hence practically useless).

    Faltzer

    I understand where the anger at PHP is coming from, and it doesn’t take a computer scientist to notice the poor language design.

    You seem to be giving them more credit than they deserve.

    I’m not sure how people writing endless walls of text about how shitty the internals are is going to help anyone switch to a better, cleaner language. Anyone knowledgeable enough on the subject to understand a lot of the points you’ve mentioned probably isn’t the one using PHP if he or she can avoid it. I reckon the “Why you should be using Python/Ruby” approach is more effective in converting people than the “Why PHP sucks” mindset. I’ve tried both, and have reached that conclusion.

    If my goal was to create converts, I would have gone about it that way, yes. However, this article was written by request from a group of colleagues I was arguing with regarding the quality of the language. I wasn't, unfortunately, focusing on that. :{

    Hm. Well, Faltzer, at least the facts are straight, except PHP does have namespaces now.

    Although as I stated to Brandon, people aren't going to use them now (the separator is ridiculous too.) PHP won't even lead an example and group their function soup into namespaces.

    And you really don’t want closures because they’ll be as ugly as hell (create_function alone is already amazingly cumbersome and hence practically useless).

    PHPs support for anonymous functions is atrocious, and create_function() is nowhere near what anonymous functions truly are.

    Thanks for the comments.

    SM

    The <code>error_reporting</code> system is very annoying, try-catch is better

    The PHP6 namespace is very weird, the operator is <code></code>. for example: <code>ProjectDatabaseClassName</code>

    Faltzer

    Nope. Try \.

    Add Comment