Hacker News new | past | comments | ask | show | jobs | submit login
I Like PHP (beust.com)
204 points by haasted on Aug 10, 2011 | hide | past | web | favorite | 263 comments

"I don’t even bother writing tests for most of the PHP I write (obviously, I would be a bit more thorough if this code were destined to be used in a more mission critical web site). Not writing tests is not the only software taboo that I break when I write PHP: I happily mix up presentation and logic all the time. That’s just how PHP is supposed to work"

And this is why everybody else hates PHP. It tempts you to write bad code, and so most people working in the language end up doing so. I have to periodically stop myself when I'm writing PHP and make sure I'm not falling into bad habits. It's possible to write good code in PHP, and I know some people who do, but the pull to write sphpghetti is too strong for most. And there is no real corresponding benefit (aside from "noobs who don't care about code quality can still write programs") arising from the design choices that cause this.

This is unfortunately true. I'm a PHP programmer (currently writing a book, A Highly Negative Book About PHP, that I've been billing as "like Essential Java but tells you what not to do") and, I like to think, a fairly good one; reading this article made me cringe because this guy is emblematic of most of the problems in the PHP community. He:

-accepts uncritically gobs of code dredged up via Google

-considers something "robust" if it doesn't break old code, when the rest of us hate it because we have to live with register_globals and other horrors

-considers "universal support" of craptastic versions of mod_php to be a good thing (some, but not all, major shared hosting messes use FastCGI)

-modifies files in production and thinks that's okay

It makes those of us who do know what we're doing and focus on disciplined code look bad, because the article author is what most people think of when talking about "PHP programmers".

I'm convinced that this post is satire and the author has trolled us all.

In fact, i reject any other explaination. Sticks fingers in ears. Lalalalala, it's satire, nobody is this incompetent. Lalalalala, can't hear you.

> PHP is exactly like C. Either you like both or you don’t like either, there is no claim you can make about PHP that can’t be made about C as well, and vice versa.

This is absolutely satire. I don't think anyone can troll much harder than "PHP is exactly like C".

Cedric used to work for Google. He was, on occasion, a brilliantly hilarious troll.

The best one has to be running your site from a git repo.

I'm not sure why running old code on an old server that has support for the old code is considered a good thing about PHP. I love BASIC because I can boot up a C64 and the code I wrote 20 years ago still works today!

> The best one has to be running your site from a git repo.

What's wrong with that? `git pull` to update everything to the latest HEAD, `git co -- HEAD~1` to roll back the latest update, `git diff` to see the latest differences, etc...

This repo doesn't have to be the development repo, just a specialized non-bare repo that's used just for production. It works great for simple sites that don't require extensive deployment infrastructure.

Careful with that, git operations aren't atomic. Safer to keep two git dirs and flip a symlink between them between pulls.

I really did consider that since the other posts by the author sound considerably more sane, but he's incredibly good at deadpan if so.

I suspect you are missing some context here.

Cedric wrote the book on unit testing (literally! [1]). He uses PHP at times when he doesn't need the reliability unit testing gives you and can't justify the extra time it takes.

Given that he works at Google, I suspect his "in production" doesn't actually mean big, real sites.

[1] http://testng.org/doc/index.html

I'm less astonished at his lack of unit testing (because I often eschew it in PHP projects, too) and more the, uh, everything else that he said that was horrible.

And I don't care if it's a "big, real" site or not, making mods to a live site is (almost) never good practice. Fix it offline, test it, push.

From your description, it sounds like Crockford's "JavaScript: The Good Parts" to me.

For the record, "PHP: The Good Parts" is downright fucking awful. Apologies to the author if he reads this, but I'll buy him a beer and restate my opinion.

I've not read any of the "The Good Parts" series, so I can't comment from personal experience, but I've heard that Crockford's book is the only good one in that series. He wrote it, and he wrote it well, and then O'Reilly decided to base a series about it, but didn't get authors who could write those books to the same standard.

This is pretty much dead on.

Weird, whenever I look up "PHP: The Good Parts" it comes back completely empty.

Haha, I get it! Because the language is bad! Oh, you jokester.

As it happens, the introduction says, verbatim, "It's like PHP: The Good Parts, but that already exists and is terrible."

So, yeah. ;-) Still a ways off, though.

"-considers something "robust" if it doesn't break old code, when the rest of us hate it because we have to live with register_globals and other horrors"

Agreed - as a PHP programmer (mainly in Zend Framework), who is now learning Python... I hate register_globals. With a fiery passion.

More importantly, as someone who hosts several photographer websites, I have a bone to pick with http://bludomain.com/ - congrats on your eighth birthday. Have you updated your code since you were born? It's a travesty that involves turning on almost every deprecated option in a php.ini. :\

Can you please provide me a resource to learn how to fully separate the code from the markup? I learned web development on ColdFusion then switched to PHP. I certainly understand separation of content from design (HTML to CSS) but I honestly have no idea how to do web development without mixing markup (HTML) with the actual programming.

I've done a little C and Java web stuff where my code printed HTML output - ugly. CFML and PHP mingle HTML and code together - also ugly, but better. I can't fathom any way NOT to mix them but would love to have some resources to see what I'm missing. I know there needs to be something better. Thanks.

Some of the other responses link to good resources, but I want to point out that "separating the code from the markup" is the wrong question -- instead what you want to do is separate business/application logic from display logic. It's okay to have an "if" statement or a "for" loop in your markup (in fact, it's necessary for dynamically outputting content), just make sure those things are specific to the display of the data, and not the creation or retrieval or "processing" of the data. For example, gat all of your data from the database first, put it all into a simple array or simple variables, then just loop through arrays and echo variables in the markup. MVC frameworks will have you put the data retrieval and prep steps in another file altogether, but even if you don't do this, at least shove all of that stuff up at the top of the php file and then at the bottom do all of the markup/display stuff.

UPDATE: Here's a stackoverflow link with a zillion more examples and resources about this: http://stackoverflow.com/questions/62617

Use an MVC framework.

I prefer Kohana + Mustache (KOStache is the module). Mustache is a logic-less templating language available in many languages. Kohana is my PHP MVC framework for choice.

Have a play around with a framework such as Symfony [1]. That's the most natural way of learning a better style of PHP web development.

[1] http://www.symfony-project.org/

Any particular reason you're linking to Symfony instead of Symfony2? I find the latter so much easier to read and work with it's not even funny.

Nope. I wasn't paying attention and did not realise that there was a new website. :)

I'm not sure about that claim. I've been working with SF for years and tried SF2 during early beta and I don't think it's that clear cut. Then again, I don't care that much so - carry on

The doc's fairly incomplete and requires you to actually browse through all the separate libraries that comprise the standard distro to even understand what you can use and where. It being OOP-tastic and brimming with interfaces and namespacing is great, but it is far from friendly to Symfony newbies.

Feels like you have to know Symfony 1 to understand what 2 is trying to do really. I wouldn't recommend it as a good intro to MVC.

The SF2 docs have really come along since the early beta. As a beginner looking at both for the first time SF2 seems more clear.

On why you might not want to mix your markup with the templating logic (copied from a blog post I wrote a while back [1]):

- Designers and developers will have a hard time working on the same file, especially the designers who don’t necessarily understand the templating rules language, and can easily break the whole thing when trying to modify the file.

- Also, when provided with a new version of the template text (say, a new version of the HTML from the designers), it’ll be hard to incorporate the modifications into the original template with all the template rules scattered inside it.

Regarding how to generate dynamic markup and not mixing the markup with templating logic, I'll cite approaches like Apache Wicket [2] (although you still need to add a couple of attributes to the markup) and server-side jQuery like select and transform templating, such as what is done in Enlive [3] and Moulder [4] (a pet project of mine)

[1] http://jawher.net/2011/01/06/on-templating-and-a-shameless-p...

[2] http://wicket.apache.org/learn/examples/helloworld.html

[3] https://github.com/cgrand/enlive/wiki

[4] http://jawher.net/2011/03/03/moulder-in-action/

Of course it is impossible to do dynamic web pages without mixing code and markup, don't let anyone tell you otherwise. It's just that in PHP it is possible to one single file that is both code and markup combined, whereas other languages require a separate logic file that sends data to templates.

That is NOT a result of the language. It is trivial in any language to combine both code and markup. However people using other languages generally work to avoid that.

That said, there is a long-standing tension between keeping logic out of templates, and giving templates more flexibility. Different frameworks take different positions on how to draw the line. PHP can be seen as an extreme position towards giving templates as much power as possible.

> That is NOT a result of the language.

Considering PHP is more-or-less designed to be a templating language, I'd say it is. Partly.

On the other hand, PHP is a pretty good templating language. People should just learn to separate business logic from presentation logic.

It is possible to write clean, well-factored code in PHP. Just as it is in other languages.

That wasn't how the language was originally intended to be written, and that is not how hordes of people use it. But it can be done. Really.

PHP is designed to be embedded in HTML. That is why you must use the enclosing <?php ?> tags in all PHP scripts. Even when you run standalone php scripts from the the command line, you're literally embedding PHP in STDOUT.

This is very different from other languages such as ruby where templating uses the ERB module, which is a subset of the ruby language.

See Enlive from the Clojure world. This is the detailed explanation of why Enlive rocks - https://github.com/swannodette/enlive-tutorial

Frameworks have been suggested, and are a good option. A good understanding of MVC will carry you through though, and if you are only building small things then an ad-hoc MVC set up will probably get you most of the way to readable, flexible, maintainable code. One good tool for separating code and HTML is using a templating engine of some sort, I adore Smarty and normally recommend it without hesitation, but have to admit that Twig seems to have all the advantages and none of the disadvantages. I haven't used Twig yet though, so I don't know for sure!

I've used twig quite a bit. Its leagues better than Smarty in every way. I heartily recommend you give it a spin. Having autoescaping built-in is a powerful and fantastic feature.

Smarty can actually do auto-escaping. Twig was specced in the Smarty 2 era and Smarty 3 and Twig ended up solving the problem in very similar ways. My biggest gripe with Smarty is how damn unprofessional it is - backwards compatibility breaking changes on point upgrades for example, and the code and "API" (I use the term loosely) is a mess.

Or another idea that doesn't require frameworks:


I like to use simple_html_dom. It's a really nice PHP library that lets you parse html structures like JQuery.


And this is why everybody else hates PHP. It tempts you to write bad code, and so most people working in the language end up doing so. I have to periodically stop myself when I'm writing PHP and make sure I'm not falling into bad habits.

You've got to keep in mind what PHP (currently) stands for: "PHP: Hypertext Preprocessor". Use it for that, and it's great, but try to make it do more and you run into trouble. IMO, PHP should be used in precisely those situations where nobody gives a shit if the code you write is any good or not, and by my reading, this was a valid point in the article.

The way I like to think of it, PHP is like Bash scripting for the web: an indispensable tool that's supported almost everywhere, useful for a quick and dirty (and sure, ugly) drop-in solution, but not a language you should "seriously develop" in. Once a project is complex enough that you need to think about how to organize your PHP files (esp. if it's real back-end PHP, not just HTML pages with functions) or manage dependencies and build processes, you've probably crossed a line and should be considering other solutions.

But on the other side of the coin, you shouldn't be thinking "Rails app" every time you need to add a hit counter and a "current time" display to a static web page, I don't care how much nicer code comes out in Ruby than PHP (and I love Ruby in comparison to PHP)...I'm getting the sense that many people here (nothing that you said, chc, indicates that, but many other comments on this thread seem to) would do exactly that, though, which is disturbing.

This might be an unpopular opinion, but I truly believe that once in a while hastily flung together spaghetti code is exactly what's called for in certain situations, and PHP excels at making that very easy to whip together and push out the door.

> hastily flung together spaghetti code is exactly what's called for in certain situations

And this, right here, is how you end up with some godawful clusterfuck of unmaintainable, throwaway spaghetti code that has become some poor fool's nightmare in a couple years. If it's worth writing, it's worth writing well. Otherwise, don't even fucking bother. Maybe this is what separates C from PHP. When Ritchie was creating C, do you think he had any idea it was going to be running the world's infrastructure in 20 years? Do you think he ever wanted to just hack it up real quick with some spaghetti code to get it working for his boss's current project? Sure he did, but instead he did the right thing. I can't imagine that Rasmus Lerdorf had more pressing concerns than the guys that were building the Unix operating system, and yet he decided it would be ok to take all kinds of shortcuts and hacky workarounds and poorly thought out design decisions when he was writing PHP. All of which have somehow permeated the language to such a point that you now have people actually defending bad code and critiquing the use of frameworks and admittedly "nicer" code!

> ...thinking "Rails app" every time you need to add a hit counter and a "current time" display ... I don't care how much nicer code comes out in Ruby than PHP ...I'm getting the sense that many people here ... would do exactly that... which is disturbing.

See, I don't find that disturbing at all. I find it reassuring. The two "simple" examples you give are a hit counter and current time. Sure, it's easy to write some PHP to increment a counter every time a page request is made. But what if it was hit from the same IP twice? And wouldn't you really like to know how long they stayed, and which links they clicked? Or maybe what country were they from and what page referred them? Hmm, maybe you shouldn't be writing a hit counter from scratch after all. At least displaying the time should be pretty simple. But wait, what if the user is in a different time zone? Did you account for daylight savings? What if the user wants a 12 hour clock instead of 24? Oh well, just hack something together real quick and I'm sure there will be plenty of time to fix it later on...

So why not use Perl then?

There's a regular stream of "defending PHP" posts but they all seem to miss the point.

No one bashes PHP because it can't do these things, or that it isn't easy. People bash PHP because there are objectively better languages and platforms out there and objectively bad decisions made by those guiding the PHP language.

If you want to defend PHP in any meaningful way then you can't just list things that can be done easily in almost every semi-modern web ecosystem, but actually compare it to the other alternatives and identify when it's the right choice. It's harder but it leads to a blog post that might actually benefit readers.

The problem is that people go too far with the bashing- People tend to just sneer at anything PHP-related, and don't acknowledge that great work is being done every day in PHP. An app written in PHP by a 8/10 programmer is going to be better than an app written in (sexy other language) by a 7/10 programmer.

> An app written in PHP by a 8/10 programmer is going to be better than an app written in (sexy other language) by a 7/10 programmer.

Depends entirely on your metric. It's far too easy to introduce subtle bugs, especially security oriented ones, in PHP. If I had a dollar for every XSS, remote file inclusion, CSRF, arbitrary file read, etc vulnerability I found in a "good" PHP app, I'd be a very wealthy man. Some things are mitigated by using a good framework, but in most cases people get them horribly, horribly wrong.

None of the things you listed have anything to do with PHP, they can happen in any language.

Oh, absolutely! Except that they're more prevalent in PHP applications than anything else. It's simply way, way too easy to do the wrong thing. If you want to introduce XSS into, say, a Rails app, it's significantly more difficult; generally, you have to explicitly throw something back as 'raw'. Sure, some PHP frameworks handle it the same way, but it's rare to see this in the real world.

While testing apps, PHP immediately throws up red flags -- it's simply not likely to be done right. It can be, but it's very rare.

That happens in nearly every language which is famous and widely used. I have seen awful Python code in the past. So bad that it would have led me to hate Python, so bad that it would have forced me to believe Python as a language sucks.

But by now I am mature enough to understand that if you hire bad programmers you get bad code irrespective of the language its written in. You can use any tool you want, if you use it badly the result is going to be bad. These are days of Python and Ruby fanboyism so very obviously everything is going to look ugly in front of it. Code bases in other languages will be declared legacy and the same thing will be translated to the new shiny language and called the 'modernized' code bases. Your RDBMS use cases will be shoe horned to NoSQL databases and declared designed for the web. This will go on and on for anther few years...

Until we get to see page long blog posts another few years from now describing how many bad Python + Django examples can be found on the net. Or how bad Python and Ruby Legacy codebases are. How framework dependency with Django, Rails or Twisted sucks. Or how someone had to spend huge engineering effort migrating from Python 2 series to 3 series. Or how they had to rewrite a large part of SQL logic to work with NoSQL databases.

This trend repeats every few years, every few years a set of tools get trolled badly.

Everyone always makes this argument, and yes you can write bad code in any language. That's a truism that contributes nothing to the discussion.

Now which languages make it easier to write more good code? Everyone talks about the lack of good PHP code and the response is "well there's plenty of bad python code out there!". What we will never see are any examples of PHP code held up as being great a few years from now.

Yes, every few years a set of tools get trolled badly. The same tools that were considered sub par by professionals at the time.

I'd like to think that the apparent security weaknesses in many PHP applications could be attributed to the fact that PHP was already around back when web security practices were more primitive.

Thus, in your career you tend see more PHP apps that were badly-implemented.

Agreed. The older a PHP application is, the more likely it is to have incredibly serious security vulnerabilities. But I've looked at and broken plenty of vulnerable applications that were written within the past couple years.

Rails is a framework. PHP is a language. If you use a framework with PHP, it's just as easy to avoid XSS. Likewise, if you use vanilla Ruby without any framework...

daeken is arguing, based on quite a bit of experience, that PHP applications (even those written with frameworks) tend to have more security vulnerabilities than Rails apps. I happen to agree with him.

One very illustrative example: arbitrary code execution. I've lost count of the number of arbitrary code execution vulnerabilities I've found in PHP applications. In contrast, I recall very vividly the last arbitrary code execution vulnerability I found in a Python application: I uploaded a PHP script to the server, which was also running mod_php. ;-)

The problem here is simple: most web servers that run PHP are configured with a rule that says "If a file ends in .php, execute it as PHP." This is useful for new users: it allows them to run and execute separate PHP scripts very easily. But it's also a potential security vulnerability if an attacker can upload a PHP file to your server.

If you're using a framework, you typically have a fixed number of scripts that should be executable and you can configure your web server appropriately. However, that requires a VPS or dedicated server.

Edit: If you're interested in an actual language-level difference between PHP and Ruby/Python that affects security, PHP scripts accepted null bytes as part of filesystem paths until recently (PHP 5.3.4, which added protection against it, was released at the end of 2010).

I'm not disputing any of that. I just get annoyed when people compare languages with frameworks. Ruby and Python have many advantages compared to PHP, but out-of-the-box XSS prevention is not one of them.

> Rails is a framework. PHP is a language.

Rails is a DSL based on Ruby to build web applications that has hooks into a rich library that helps with that. PHP is a language designed to build web applications (although it can be abused to write any type of application)

> If you want to defend PHP in any meaningful way then you can't just list things that can be done easily in almost every semi-modern web ecosystem

Did you ever read Python's documentation? Or Ruby's? Or Java's?

Show me one popular web programming language which has a full page, up to date, with examples and user comments and version incompatibility info, per function.

Of course, it's just one point and I otherwise agree with your comment, but it's one hell of an advantage.

> user comments

Ha-ha-ha. You're kidding, right?

Check strlen: http://www.php.net/manual/en/function.strlen.php


1. Comment about how PHP converts types. "Conclusion: The values are converted to string before check the lenght."

2. Comment from a novice user who posted a solution to the problem of subtracting the number of spaces in string from its length.

3. Comment about someone who thought that there was a bug in strlen, but it actually was a documented difference in behavior between two minor versions of PHP.

4. Comment about counting characters in UTF-8 encoded string by decoding it to some other one-byte encoding.

5. Comment about counting characters in UTF-8. Actually, the whole new function.

6. Reminder that \r\n are actually two bytes! "If I had thought of this starting out, I would have saved myself several hours of trouble trying to get php to cut a message to the same length that my auxiliary javascript validation imposed on it."

7. Benchmarks for different UTF-8 strlen implementations.

8. Complaint about another comment, which suggested the function to count characters in UTF-8 strings that didn't work. And the "proper" solution using regular expressions.


When I wrote some php years ago, the comments were actually useful. They had the most up-to-date information about the latest bugs in the php standard libs.

It may just be a side effect of PHP's problems, but even the wrong comments tend to be extremely useful when you run into something weird when coding. Of course it's always more fun to bash people & programming languages, so maybe I'll just join in: that bloody Ruby API reference lacks any comments from users who might have noticed something that's causing a strange bug in my script.

As much as I love Ruby, I have to say that the Ruby docs website is shit. No search bar (unlike the PHP docs website).

Agreed. I use http://rdoc.info/stdlib/core/1.9.2/frames which has search and a nice UI.

Thanks, I haven't laughed this much in a long while.

Um, Python's documentation is separated by release versions - so you can read a doc page that specifically targets the version you are using. That is the right way to do it; with PHP you would have to read the doc page, then also go read any deprecation warnings or caveats for the possible version you are using. What a nightmare to maintain too. Plus, I have yet to come across a Python doc page that doesn't provide usage examples!

I can't speak for Ruby or Java because I haven't even looked at their documentation sites.

User comments? PHP user comments are crap, IMHO - so many people writing so much horrible code in those comments.

I understand where a lot of PHP supporters are coming from because I was once there - I spent four years with the language and thought it was the most beautiful thing that existed. Until Python, Scheme, Erlang, and Haskell invaded my life.

PHP will always be an amateur programming language - which is it's strength, kind of like BASIC, a great stepping stone but nothing more.

So right! PHP is the Basic of web programming languages.

I'll bite, speaking for Python, because that's the one I'm more familiar with.

1. Python doc has full up to date documentation for everything shipped with the standard library (which dwarfs PHPs grab bag of globally scoped functions)

2. The comments in PHP documentation are frequently out of date, misleading, or flat out wrong. Among the people I work with (who are working on PHP web apps, full time) everybody routinely advises the PHP noobs to ignore the comments.

3. The standard library functions shipped with most languages don't require a full page with multiple examples to explain how they work.

Don't get me wrong, the documentation for PHP is excellent, but it's a small win for a language that has so many real --language level-- issues.

Python's got excellent documentation, both official and third party.

Python itself does, but the third party modules (which do most of the heavy lifting) generally don't. See: Twisted.

Perl is a good example where most third-party modules have good documentation. Or at least a SYNOPSIS you can poke, some DESCRIPTION of what the module does, and a few hundred lines of code in the t/ directory that test all the features of the modules.

The one thing I miss in Python is the inability to click "view source" in my web browser to see how a core Python library is implemented. PHP also has this problem. (Code is the best documentation. Learn to read it.)

If you're talking about the search.cpan.org links to source, I'm right there with you.

The only thing I wish they had was a way to pipe it through a highlighter like perltidy with html out. That'd probably just lead to holy wars on formatting/colours though.

Awesome. search aliases duly updated.

Twisted has semi-decent documentation, see




It's not as comprehensive and shiny as the core Python docs, but along with the tutorials and examples, it's actually pretty decent.

There's high variation in quality amongst third-party modules, but the "modern" python community takes documentation quite seriously, there's even a complete site dedicated to nothing but hosting compiled documentation[0]. Projects like Django, Flask, SQLAlchemy or Flask have rather good documentation sets.

[0] http://rtfd.org

Third party documentation doesn't count in this discussion.

It does when one of the big criticisms of PHP is that it rolls everything into core that'd normally be third-party.

Considering how PHP doesn't have anything like Twisted (and this is just one example out of many) ; no, it doesn't count.

Also, I never used a popular Python library for which I haven't found good resources.

My favorite Python library, called NLTK, which has no equivalent in PHP or Ruby or any other platform for that matter, comes with a freaking book that's available for free.

Oh! Well, I must've missed that train (haven't done py for a few years). A couple of years ago, you had to get your info from a mix of a tutorial and a library reference, and most functions were documented with 3-4 sentences max and no examples.

Hmm, that said, that's still exactly what I find on the official Python site (e.g. http://docs.python.org/library/stdtypes.html#string-methods - PHP beats this by lightyears with a single page with examples and comments per function). Which 3rd party thing should I be looking for? (genuinely interested btw - the docs is one thing i dislike about python, and maybe unrightfully so, apparently)

> e.g. http://docs.python.org/library/stdtypes.html#string-methods - PHP beats this by lightyears with a single page with examples and comments per function

1. Please explain why you need more explanation of these very basic functions

2. PHP's doc comments are unadulterated garbage

3. When things are worth documenting, they are: http://docs.python.org/py3k/library/collections.html

4. if you truly think string methods are insufficiently documented, it is very easy to contribute to the documentation.

Frankly, no. Just no.

The REASON PHP needs a page per function is the sheer number of poorly handled edge cases, version incompatibilities, and gotchas.

Maybe you're looking more for a tutorial, and not a reference? I've always found the online Python docs excellent, and provided me with exactly the information I need.

> Did you ever read Python's documentation?

Yes. it's rather fucking good.

> Show me one popular web programming language which has a full page, up to date, with examples and user comments and version incompatibility info, per function.

Have you ever read Python's documentation? In the last ten years?

Python's docs have a complete and readable description of the language[0] including its data model and the various core protocols[1], it has a number of quality howtos and guides[2] a complete documentation of how to use C-level APIs[3][4], a pretty good and complete tutorial for beginners[5], a complete, well written and exhaustive changelog with examples[6] drilling down to C API changes[7] and most stdlib modules are extensively documented with examples and links to to the actual source code for the module[8] and versioning information[9], with the whole documentation being heavily hyperlinked and permalinked (every section, subsectio, sub-sub-section, class, method, function or constant getting its very own anchor) linking to its own source[10]. And just in case you want to contribute, or even just want the documentation offline, it's included in the source tree and trivially compiled to not only an HTML version, but a PDF (via latex), plain text or EPUB one as well[11]. Hell, the documentation is so extensive there's even documentation on documenting[12].

Oh, and the documentation is available for every single version of Python past, present or future (for which it could be found anyway, as far as older versions of the language are concerned), including bugfix releases[13]. And then it goes the extra mile by letting you run examples to ensure nobody broke them[14].

As to "full page per function", I really don't think you need that. And the PHP doc comments are closer to youtube comments than to anything worth reading, I simply can not see them as anything but liabilities.

[0] http://docs.python.org/py3k/reference/index.html

[1] http://docs.python.org/py3k/reference/datamodel.html

[2] http://docs.python.org/py3k/howto/index.html

[3] http://docs.python.org/py3k/c-api/index.html

[4] http://docs.python.org/py3k/extending/index.html

[5] http://docs.python.org/py3k/tutorial/index.html

[6] http://docs.python.org/py3k/whatsnew/3.2.html

[7] http://docs.python.org/py3k/whatsnew/3.2.html#build-and-c-ap...

[8] http://docs.python.org/py3k/library/collections.html]

[9] http://docs.python.org/py3k/library/collections.html#collect...

[10] http://docs.python.org/py3k/_sources/library/heapq.txt

[11] http://hg.python.org/cpython-fullhistory/file/tip/Doc

[12] http://docs.python.org/documenting/index.html

[13] http://www.python.org/doc/versions/

[14] http://sphinx.pocoo.org/ext/doctest.html

(the lack of markup in HN comments is getting seriously annoying)

Don't forget being able to do this from within the interpreter:

    >>> print abs.__doc__
    abs(number) -> number

    Return the absolute value of the argument.
    >>> print xrange.__doc__
    xrange([start,] stop[, step]) -> xrange object

    Like range(), but instead of returning a list, returns an object that
    generates the numbers in the range on demand.  For looping, this is 
    slightly faster than range() and more memory efficient.

True, or from your OS's shell:

    > pydoc unittest
    Help on module unittest:




        Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
        Smalltalk testing framework.
        This module contains the core framework classes that form the basis of
        specific test cases and suites (TestCase, TestSuite etc.), and also a
        text-based utility class for running the tests and reporting the results

Or from ipython, even better:

    In [1]: abs?
    Type:		builtin_function_or_method
    Base Class:	<type 'builtin_function_or_method'>
    String Form:	<built-in function abs>
    Namespace:	Python builtin
       abs(number) -> number
    Return the absolute value of the argument.


    In [1]: import json
    In [2]: json.dumps??
    Type:       function
    Base Class: <type 'function'>
    String Form:<function dumps at 0x101f0bc08>
    Namespace:  Interactive
    File:       /usr/local/Cellar/python/2.7.2/lib/python2.7/json/__init__.py
    Definition: json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, **kw)
    def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
            allow_nan=True, cls=None, indent=None, separators=None,
            encoding='utf-8', default=None, **kw):
        """ [snip (excellent) docstring] """
        # cached encoder
        if (not skipkeys and ensure_ascii and
            check_circular and allow_nan and
            cls is None and indent is None and separators is None and
            encoding == 'utf-8' and default is None and not kw):
            return _default_encoder.encode(obj)
    #snip rest of func

I usually use the help function, instead of reading __docs__ directly.

Everyone is mentioning Python, but also check C# and .NET Fx and ASP.NET MVC.

For example: http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx



You get the syntax (including VB, C++, and F# where availalbe), remarks, examples, version information, platforms, comments, and related content.

MSDN is crap. It is just complete for completeness sake. You get the syntax, remarks, examples, version information, platforms, comments, and related content, but you still can't find what you are looking for.

What used to drive me especially nuts about MSDN documentation (when I used to write C#) is that they seem to change the URL scheme every year or so, just so that every reference to anything breaks every single time you try to look at it.

I mean, just look at that first URL!

User comments in PHP doc pages IMO is a whole lot of noise. Not that I am saying there isn't a place for something like that but the official doc is just not the place.

User comments don't belong in documentation.

As far as I know, PHP is the only major programming language that considers itself a "web programming language."

> PHP is exactly like C. Either you like both or you don’t like either, there is no claim you can make about PHP that can’t be made about C as well, and vice versa

* C is fast and has tight resource control

* C is portable

* C has a transitive (==) operator


Yeah, clearly this is a troll blog. Congrats to the troll.

I sort-of felt like this comment was added in his post to get the blood boiling a little.

I love his other points about PHP (as I too like PHP), but I felt this was one of those bold statements that was a little sensational and attention grabbing at best. I too find it pretty far fetched.

I honestly don't intend this in a mean way (I mostly code in PHP at present), but if you loved his other points you might want to delve a little deeper. PHP is a good enough language, but a lot of what he is saying is either incorrect, poor form, or championing solutions to problems that simply don't exist in other languages.

From the comments: "PHP is great for its purpose. Quick scripts that generate web content. It’s even OK for small applications. But just like C, PHP is lousy for the medium to large. Any software project with a duration in months or greater that is entirely in PHP is going to be painful."

Like Facebook? Or Wordpress? Or Digg?

PHP aint perfect, but it's demonstrably suitable for medium to large projects.

Do yourself a favor. Never ever use wordpress as an example of a quality PHP application. Please look at the source code, the open source wordpress is a monstrous hack that has no clear architecture, has a terrible system of hooks that plugin authors regularly abuse and doesn't scale unless you write your own hack of plugin to override the db handler so you can do things like r/w splitting or sharding.

Any suggestions for PHP applications whose source code can be presented as an example of what TO do instead of what NOT to do?


http://flow3.typo3.org/download/ This is still in alpha but has good source code regardless.


There is little indication that Facebook isn't painful to deal with compared to a functionally identical version of Facebook built in another language/platform. Because someone did it and is profiting from it does not mean they could not have done it better.

Considering Facebook uses Haskell to automate changes to their PHP codebase, I'd imagine PHP isn't doing them any favors.

I heard about that tool. Can you tell us more about what it does?

It is called lex-pass [1], it does syntax aware transformations of PHP. Like sed, but specifically for PHP. There is a video that mentions it briefly at 2:00 min [2].

[1] https://github.com/facebook/lex-pass [2] http://www.vimeo.com/6699769

I thought most of Facebook's php is written in a subset of PHP that can HipHop can compile for them. I doubt their PHP is all that similar to eg. Wordpress's PHP.

I thought FB's troubles were with mysql not PHP. Turns out mysql has some limiting factors.

Turns out * has some limiting factors [when serving 1 trillion page views a month]. Replace "*" with any piece of technology on the web stack.

There's not a single other company in the world (sans probably Google) that has to deal with performance problems on that level of scale. At that point, I can't imagine anything surviving out-of-the-box. Something has to give, even the language they're using (they're using a subset of PHP that they can run through a custom compiler to C++ machine code, to squeeze every possible CPU cycle out of the servers they have).

You can build a Tinker-Toy computer that plays Tic-Tac-Toe, but just because you can doesn't mean you should.


I think it's probably easier to create unmanageable spaghetti with PHP. It's not that you can't build a large project in PHP, it's that it's easier to foul up.

By far the part of PHP that shines for small projects and causes havoc in large is the way includes work. It's possible to be disciplined about this, but it's not common. I remember many times searching in vain for some function or another that was included somewhere, somehow. Sometimes even in code that I wrote entirely!

Facebook and Wordpress and Digg being in PHP isn't a decision that was made with a large architecture in mind, it was done because the people who wrote those projects knew PHP (And in Wordpress's case, because the people who use it need it in PHP).

One of our struggles at Facebook was actually with circular includes that made our php codebase super tasty spaghetti.

File A includes File B includes File C includes File A by about 10000 files.

It was for a very scary trying to change a core library during this time because it was almost impossible to figure out where all it was included and impossible to test all the code that touched it. Additionally, we were basically loading up our entire init stack on every page load and async request because as soon as you loaded up one file all the circular dependencies would load up the entire stack. This had a big performance overhead prior to our switch to HipHop.

To this end we developed a new include system for library files that forces developers to be sane. Every module in the our library files must explicitly include everything that they need and it forbids circular dependencies. If module A requires module B, module B cannot require module A.

Making this change took a long time (in some places we are still untangling the code), but our core code is now infinitely more manageable and most importantly testable.

I worked on a large PHP codebase for a few years, and that sounds very familiar. We never did get it untangled enough to test before I left.

Do you have a static analyzer or something like it that enforces the no-circular-dependencies rule, or is it just a procedural thing?

We have a static analyzer that runs when we submit a diff yes or try to commit, but in our "require_module" we also check for circular dependencies at run time. If you create one you get the module stack dumped into your log and promptly exited with an error message.

That sounds like it could be useful to the PHP community. Are there plans to open source it?

I'll look into it. Not sure how tightly coupled it is with some Facebook specific stuff.

http://phabricator.org/ has a very similar system if you are curious. epriestley made some nice updates to it in there as well.

How does Facebook use Autoload? Does it help in this situation?

You can't blame PHP because the developers using it write messy code.

I'll have the same problem in Java. I'll need to find out where I implemented some logic, and have to start digging through classes and following my own breadcrumbs until I find it sometimes.

Just because I commented my code poorly, or put logic in the wrong place isn't the fault of Java, it's my own, and the languages, Java and PHP, in my opinion, are easy and fun to work with for the most part.

It happens with any language. But at least in Java you're limited (as far as I know) to looking through what you've explicitly imported. If you include a file in PHP, you have access to everything that that file included in itself, and everything that those files included, and so forth.

Excuse my ignorance, but don't you have the same behavior with `require` in Ruby? How are the behaviors of Ruby's `require` and PHP's `include_once` different?

Today not many people create large apps without a solid framework at the bottom, be it Zend, symfony, Rails, Django or whatever. Wordpress is pretty awful but the codebase is also pretty old, rewriting everything would be loads of work and make many plugins unusable.

It's a damning indictment of Java, ASP.NET, Ruby and all other environments that almost all of the apps that "any idiot can install on a web server" are written in PHP.

Where's the "Wordpress" of any other programming language?

There is a strong correlation between things whose primary design criterion include "any idiot can install", and "complete crap design".

As examples I hold up PHP, most PHP applications, MySQL, Matt Wright's script archives (a series of security holes masquerading as useful Perl scripts that were popular a decade ago), and so on.

The correlation is hardly absolute. For instance SQLite is both excellently well designed and also designed for easy install. However it holds often enough to strain coincidence.

My suspicion is that part of it is that something that is designed to be trivial to use tends to have a low barrier to entry to get involved with. This leads to getting contributers with more enthusiasm than skill.

Early on, PHP had the advantage of mod_php, which made deploying PHP applications simple and performed well. Because other languages required more complex setup (e.g. fastcgi, servlet containers) shared hosting providers gravitated towards supporting PHP applications. This caused open source projects that used PHP to gain more traction than projects written in, say, Perl. Eventually, hosting providers realized mod_php was not such a good idea. See the following link for an expansion on that http://www.majordojo.com/2007/11/is-mod-php-falling-out-of-f.... I think the shift of shared hosting providers to FastCGI (which makes supporting additional languages less work) as well as the decreased cost of private servers due to virtualization is playing a role in PHP's apparent decline in popularity.

Before there were lots of easy-to-use self-publishing apps, it made sense to install your own on a $5/month host. Most people nowadays use Wordpress, the service, not Wordpress the PHP package.

Is developing for Facebook not painful?

I imagine most of us do not work at Facebook and have no idea how hard working on their code base is.

There's not necessarily any connection between developing external Facebook applications and working on Facebook code itself.

Is developing anything of that size, in any language, not painful?

That's like saying because the Pyramids were built in stone, we should build all our skyscrapers in stone. I bet that if Facebook, Wordpress or Digg were built in Ruby on Rails or some other modern language, they would be exponentially faster and easier to develop and maintain.

Most of the time, performance is more a factor of system architecture and choice of algorithms/data structures - and less about the language you're using.

Unless you're doing very CPU intensive computations where every millisecond counts, the difference between most languages won't be that great in the big picture.

The quote was "they would be exponentially faster and easier to develop and maintain".

> I bet that if Facebook, Wordpress or Digg were built in Ruby on Rails or some other modern language, they would be exponentially faster

I'll take that bet.

They'd probably be linearly faster.

Thanks to PHP or in spite of PHP?

Are you saying that Wordpress development isn't painful? Have you ever done any?

> PHP is like C

In all the bad ways, and none of the good ones.

I like MJD's quote the best: "Like C without the speed, like Perl without the toolbox"

Yeah... the author pretty much lost all credibility after that sentence for me. If C was a Formula 1 race car (fast, dangerous, designed by the most brilliant minds in the industry), PHP would be a Ford Pinto (cheap, convenient, ugly, and very likely to blow up on you out of nowhere).

My first web language was PHP, I started working with it 12 years ago. Back then you didn't have Rails, Django, ORM, unit testing (in web dev that is), and javascript was looked as a language to just show popups and have confirm()'s before submitting forms.

If you wanted to connect to a MySQL, you have to do it all by yourself, you need to create a database, tables, PKs, connect to database, execute RAW mysql queries, and so on. Form validation ? Yeah right. Back then the include_once() or require() were amazing for separating code. But all in all that mades us learn how things work internally, how HTTP requests work, how SQL works, even why CSRF or XSS and SQL injections are executed.

Yes, the code was shitty, it was all over the place, but we learned how a web app works internally.

And yet, most developers I know who coded PHP back then are amazing developers today in any web language or framework. Why ?

Because most of them learned doing things the hard way. We had to understand how HTTP requests works, how SQL works, etc..etc.. because we didn't have the magic of rails, or any helper for any framework.

In these 12 years, web development as grown, a lot, and for the better, I'm currently learning Rails, and I've already done a project with Django and Node.JS . I liked them a lot and they are amazingly well done, I just wished PHP was more OO like ruby or python.

However, I laugh at these new Rail/Django developers that joke about PHP code. Most of them start coding jumping immediately into a framework. I bet that most of then couldn't create a simple MVC framework, ORM from scratch, hell, even a simple security CSRF would be a pain without "gem install <whatever>".

You see kids, PHP was like our first GF or our first car, where we tried stuff, made us cry (in a sense), and helped us grow and mature as developers, for those who wanted to grow that is. Now you have lots of languages for web dev, but back then PHP was the thing.

I still believe that PHP is a very cool language if done correctly, I wished tho, that it should be rewritten to be more OO.

But if one thing I learned from all of these years is that, it's the developer who makes quality code, not the language. Unless that is, you are using a framework who basically demands you to do things the way it wants, and puts a lot for magic so you don't bother with "boring" stuff. But in the end of the day it's not your code, it's theirs.

So my advice for new dev is, forget frameworks, and learn the hardcore way, then pickup a framework you love and go with it, either PHP, Ruby, Python or whatever.

I don't think it's a good idea to advice newbies to learn the hardcore way. I'm exactly like you, started with PHP, had to do everything manually, etc... except I have a different opinion.

The reason you and I and all the others like us put in so much effort in solving problems in PHP like CSRF, XSS and SQLI was because we were passionate enough to learn about that and then implement solutions for it.

Developers who don't care about security measures like that - they're the ones who store plaintext passwords, still - won't care either way, no matter if they're using Rails or PHP. Frameworks like Rails solves it for them, but if it weren't for Rails, their apps would have all these security problems, and they would only be addressed once disaster strikes.

Those that do care will be passionate about their work. They are the ones that read up on XSS and CSRF out of interest, not necessity. I'm sure they look at the generated HTML source once in a while, and then wonder why they add that token there. Using Rails, newbies are exposed to the solutions from the start, encouraging them to learn about it. As a PHP newbie, you're never exposed to the problem or the solution, until you start reading about security on your own or you get into trouble.

The point was that a good programmer is a good programmer regardless of their tools. And a bad programmer will always be a bad programmer no matter how much their tools do for them.

Spend time becoming a good programmer, and you'll be better off in the long run. If you don't want to spend that time, go find another profession...

"There is nothing more exciting than modifying a file, hitting Refresh on your browser and seeing the result right away"

I think this feature is definitely useful, but you can virtually do the same thing in other languages with templating engines.

Exactly. This is not a feature of PHP, but simply CGI.

It's a feature of PHP because PHP isn't a compiled language. C, Java, anything .NET... They all require an added step in the middle.

You haven't done much asp.net development I take it?

Not for many years, no. I'd forgotten about it.

Still surprised I got voted down for that, since C and Java are still correct.

In fact, it's what I hated about Java web development the most... You had to compile, package, and deploy every time you made a tiny change. It was a nightmare.

Even in some parts of the Java world, that problem doesn't exist anymore.

The Play framework uses its own copy of the Eclipse compiler to compile everything on the fly while it is running in development mode...so as you as you save your changes, you can reload your browser and see them immediately.

There are frameworks for Java that doesn't require you to compile / package / deploy for each change. One example of this is http://www.playframework.org/

in .net you can run your site off source files, and the server will compile as needed

It's slower, right? I remember some years ago it would take like 5 seconds on this kind of big web app to show me the newer version of the file I just changed.

In production, or just your dev environment?

You technically can compile ASP pages on the fly in production but it's bad practice, just like making changes directly to production is bad practice. The whole blog post is pretty much a great write up of how not to manage a website.

He was talking about small sites, in which case a deploy script, etc. is probably more trouble than it's worth.

Was I incorrect that he was talking about small sites, or do people just believe that every site regardless of size should use a deploy script and the other trappings of large application/high volume production development? Because the latter is silly.

He was but I don't think that's a valid excuse.

Doing a tested change and then a pushing to production is a 4 command overhead using git as lazily as possible with maybe an additional 5 minutes spent during initial project setup. You're doing the same coding work, you're just helping to ensure it's not going to create any completely useless work spent undoing mistakes. It's an ounce of prevention, pound of cure argument in my mind.

It's really not that clear cut. To do what you propose, you either have to set up an identical staging environment, or you have to set up a local environment that mimics (and stays in sync with!) the production environment. For a tiny site that sees <100 people a day, where the potential damage of a mistake is absurdly low (so what if 5 people see the broken version while you make corrections?) it's not necessarily worth the additional hassle.

This all depends on what kind of site it is, of course, but in the context of what he's saying, it makes sense.

With additional setup, yes, but PHP has a fast development cycle out-of-the-box which I think is significant.

This mind-bendingly important. In 1999, you could download one single installer on Windows, run it and with literally no further configuration you'd be writing PHP on an Apache/MySQL stack. No other environment even came close at the time and for a long time following.

This is still the main reason why I use PHP: the development cycle is just so fast, and if you are experienced enough to write good code without anyone holding your hand, you can do great work in PHP in a much shorter period of time when compared to most other platforms (at least the ones I've tried).

When people criticise the PHP language I think they really miss the point: it is the PHP platform that is really powerful because of:

1. The shared nothing architecture (it really helps you scale).

2. The rapid development cycle.

3. The portability (Apache, IIS, nginx, persistent in-memory interpreters via PHP-FPM...).

4. The huge amount of native C extensions providing amazing functionality.

Sure the language has warts, but who cares when the platform is this powerful?

As someone learning, I figured out pretty quickly from many forum threads about this topic, that I was simply too ignorant to be confident in writing solid PHP. I am in no rush to do anything useful (just having fun), and I'm trying to concurrently learn Vim and Git. so I chose Python. I might try PHP, if I ever feel I have learned to write OO code competently.

tl;dr: Too many gotchyas for a beginner. I need discipline imposed on me when I'm learning, ymmv.

Yep. And compared to Rails, something like mod_php is just so much faster and less resource hungry, it hurts. I use both regularly in production, and scaling the PHP side is almost trivial compared to the rails side.

Sorry to nitpick but that isn't scaling. Unless I can add double the number of machines and double or almost double the capability, and keep doing so to thousands of machine your application doesn't scale.

In the case of web applications all tend to scale equally well as you can just add another web server. Its the database that causes the scale issues.

Scaling vertically is still a valid strategy, and is scaling. Not every company needs to be able to scale to the moon, and if they don't, it's a poor use of time to focus too much on architecting for scalability.

With a lightweight PHP framework and a sensibly written app, you can stick to one machine for much longer than you can with Rails, and after that, it will require a fraction of the number of app servers. Beyond that, app processing time is generally much lower without all of that cruft, so you don't need to do as much caching, etc. to get a snappy webpage.

Maybe its just me but I don't consider "scaling up" as scaling. In my mind scaling means running on more then one machine.

Don't get me wrong though, throwing a bigger hardware box at a problem is a totally viable solution to most problems, up-to a point.

Where I work, we've standardized on PHP and I have no choice but to use it. It isn't as bad as people say that is! Our organization's product is a large application written in object-oriented PHP with unit tests for every method of every class. As a team, we use continuous integration and have regular code reviews to promote quality. We've done some things that we're not proud of, but on the whole our codebase is pretty clean and elegant, and at the end of the day I'm almost always proud of the work I've done.

What worries me about PHP is that innovative ideas don't appear to be coming from the PHP community. They come from Python, or Ruby, or Erlang, or Java projects and are copied by PHP developers afterwards. I worry there's a risk that PHP is being left behind as the developers who solve new and challenging problems turn to other languages.

Furthermore -- and this is just my sense of how things are where I live -- while it's possible (and not even difficult) to write quality PHP code, it seems to be difficult to find developers who care about quality. My manager complains about this constantly and I'm inclined to believe him since, when I was a freelance developer, I saw tons of PHP code that was simply and unambiguously terrible. Conversely, a developer who wants to write quality code in PHP has to look pretty hard to find a PHP shop that recognizes quality and values it. I suppose that these issues aren't tied to a particular language, but they seem more pronounced with PHP.

PHP's greatest strength is that it doesn't require OO. Seriously, for most simple web application tasks (and even some complicated ones) OO adds more confusion than it removes, and I say this as someone who certainly sees the value in OO for complex apps.

Most web apps are ultimately more like shell scripts or console applications than desktop/mobile applications. It's no coincidence that most of the former are written in C or C-like scripting languages, and most of the latter are written in OO languages running on .NET or Java. Your basic operations are "print some stuff", "read from a file or database" and various sorting, slicing and text-processing tasks inbetween, all of which are done well by PHP, Perl, C and so forth. ActiveRecord, TableDataGateway etc. are great patterns for data access, but sometimes mysql_query("SELECT foo FROM bar WHERE x = y") is just so much simpler that it becomes the better option.

The lack of OO makes PHP's documentation much more browseable, and makes code more readable in certain situations. If I look at your code and I see a function I don't know, I just google it. If I see a method invocation on an object, I need to figure out the type of the object (not easy in a dynamic language) and google the combination of class and method name, which often fails to return a result (has anyone ever managed to find anything useful in the Zend Framework docs?). PHP isn't the only data point for this argument - I think it's probably why Drupal handily beats ZF, Symfony etc. in terms of popularity, despite the superior OO architecture of the latter. You can google pretty much any API function and get an accurate result, which you just can't do with ZF (which lacks documentation at the method level, and what documentation that exists is buried in some Doxygen-based site which is made impervious to search by the use of frames). I'm also reminded of Linus's argument against OO in the Linux kernel - when you're all about the patch files, you need clear function names to understand what's going on without massive amounts of context. Drupal's rate of contributions probably exceeds that of other frameworks for similar reasons.

Of course, this bias against OO is also what makes PHP a bad choice for certain things, and this is why plenty of devs hate it. I honestly don't know if, in the final analysis, this makes PHP a good or bad choice. It probably depends too much on the problem you're trying to solve for there to be a simple answer.

I don't think you really mean "object orientation" so much as "a byzantine object hierarchy" (stereotypically associated with Java, of course). To me, Ruby's object-oriented string functions are a lot easier to keep track of than PHP's:

x.length vs strlen($x)

x.gsub('foo', 'bar') vs str_replace('foo', 'bar', $x)

x.strip vs trim($x)

x.upcase vs strtoupper($x)

All four of the PHP functions use a different form: strX, str_X, X, and strtoX. Some of this could be solved with consistent function names, like always using str_X, but then that makes me wonder why one wouldn't just want to have all string functions available as object-oriented methods on strings. Python takes a different tactic, and has a non-object-oriented len() method, but this isn't just used to get the length of a string, it will also get you the length of a list, tuple, or dictionary.

     Python takes a different tactic, and has a 
     non-object-oriented len() method
What do you mean?

In Python len() is just a standard protocol for getting the length of something, but len() itself is calling obj.__len__() if it is defined. You can even override or replace it in an object instance, returning whatever you want.

You can argue that these protocols are a bad idea, or maybe a useless one since Ruby does just fine without such hardcoded conventions, but since it relies on runtime adhoc polymorphism, it is as object oriented as it gets.

I meant it only in the superficial sense, that the call of len() is called as len(foo), not foo.len().

I guess this is another example of why using the term "object-oriented" at all can be unhelpful, as it may mean so many different things to different people depending on the particular situation.

What's so hard about OO? Instead of string_length($string), you write $string->length. The semantics are the same. If you pass something other than a string to string_length, the results are undefined. If you call length on an object that doesn't do the length method, then you get an error.

The attraction of PHP is that it never tells you that you're writing code that doesn't work. The result is a lot of code that doesn't work. This is bad, not good.

A tricycles greatest strength is that it doesn't require balancing on two wheels.

For those who can't ride a bicycle, tricycles are great.

Once you understand how to use a framework/language like RoR, I don't see how PHP is more useful (unless you have size constraints). ActiveRecord::Base.connection.execute("SELECT foo from bar where x = y") is just as simple as mysql_query("SELECT foo FROM bar WHERE x = y"), and you get the benefit of abstracting away the database in database.yml so you can run it in different environments.

the db_query() function in drupal also does that abstracting.

Yes, but the OP was talking about framework-less simple projects.

Google isn't the best place to look for object/method references. I've worked with a lot of large PHP codebases and the answer is always in the local source files or, if they're too obtuse, then on the project's documentation (if it exists and is current), in the PHP manual, or in a Google search result.

Any editor worth its salt can manipulate a cross-reference of the project's symbols. Learning how to do this has saved me days of time figuring out OO-heavy projects. I prefer ctags(1) and Vim.

This comment is almost better than the blog post itself:

> But just like C, PHP is lousy for the medium to large. Any software project with a duration in months or greater that is entirely in PHP is going to be painful.

Yeah, C is terrible for medium to large projects like, say, Linux.

C is one of the few languages Linux can be written in. That doesn't mean it's the best for the job.

I'm just glad we're at this point where there are so many quality languages and frameworks available that we can fuss over which one is best. That is all I'm going to say on the subject.

> I write PHP code very sporadically

Explains it. PHP is fine if you jump in, write a few lines, and then don't ever have to maintain it yourself. Woe to the guy who does have to maintain it.

Absolutely, and I'm sorry if my article didn't carry this point across.

I would never use PHP for anything big/complex, my post was mostly in response to the universal sneering and mocking that PHP always gets. I think it's unjustified.

Since I only modify my web sites a few times a year, I am pretty sure that I would be much more reluctant making these modifications on a RoR app than a PHP one.

I like PHP because it's got a C-like syntax, which is a personal preference of mine. I also like it because it exposes the nuts-and-bolts of web development without any fuss, unlike, say, ASP.NET (though last I touched that was 3 years ago so doubtless things have changed since), and that it has a basic templating system built in, and that it's easy to install and deploy to.

It definitely is deeply flawed for many reasons, which is why I'm still looking for my "white unicorn" language: one with a C-like syntax, no fancy templating or ORM magic (just let me print() html), foss, easy to deploy, and with an established community and searchable "recipes" online.

Lots of languages fit some of those criteria, but I haven't found one that fits them all.

Uh, Perl?

I wouldn't write this kind of Perl, but Perl is not going to get in your way. "use CGI; print html(body(p("OH HAI")))".

When you realize that this sucks and you can't maintain it, you'll be able to gradually improve your code. First, you can run your CGI from Plack instead of Apache. Then, you can start using features from a Plack-based framework, like URL mapping. Next, you can move your "print this HTML" into template classes. Then, you can convert these to using TT (or similar), and your app code won't notice. You can start writing unit tests. You can gradually migrate your raw DBI calls to DBIx::Class by using $schema->dbh_do.

You won't have to do it all at once and you won't have to break any code when you do. Perl will grow as you do. Or, you can stick to CGI forever. It doesn't care :)

It's a great language for starting small and building up "complexity" as you learn more about programming.

For ASP.NET, indeed, WebForms can be a bit violent since it's essentially an abstraction that tries, with mixed sucess, to make you forget you're writing for the Web.

ASP.NET MVC, which came out 2 years ago, is much closer to RoR and other similar frameworks, and is a better abstraction in my opinion.

I don't think Microsoft is even still developing WebForms (last release is April 2010). Too many aspx sites are written in the old version of WebForms which turned the html output into a horrible and ugly mess. MVC3 is pretty much just as good as RoR or any other mvc framework about outputting clean html.

Stopped reading when I came to:

"Sometimes, I don’t even bother editing the files locally and then transferring them: I ssh to my server and modify the files live."

More than providing any defense or justification for the use of PHP, this article greatly bolsters the opinion that PHP is for noobs.

You can do anything web related with PHP, it might not be the coolest kid in town but it gets every job done pretty well in the space it has been designed for. Use a framework like symfony and large scale applications with decent design are no problem at all in PHP. Same is true for Python, Ruby etc though, so just use what suits you best. Comparing it to C ? Dunno, completely different animals. I wouldnt do web dev in C, but i also wouldnt do graphics programming in PHP. Just because they both are not designed with OO at the core doesnt mean they are exactly the same.

My observations for the popularity of PHP are this:

1) It's old. You're alternatives to PHP 12 years ago are all bad. The most popular alternative was perl CGI scripts.

2) Since it's templated, it feels more like markup . Someone with absolutely no programming background can go: HTML -> HTML with a javascript "onclick" handler pasted from the web -> HTML with a bit of PHP pasted from the web -> writing my first original PHP code

PHP's one great strength is that it can be effectively used in a very wide range of applications. But doing that well requires using the language in ways suited to that purpose.

The problem with people "defending" PHP is that they often only use PHP for a very specific purpose, and describe PHP from that perspective.

Hacking quick and dirty procedural scripts, writing something like WordPress plugins or developing "enterprise" applications with frameworks like Symfony or Zend are entirely different ways of using PHP, usually done by entirely different kind of developers.

The unmaintainable crap PHP is infamous for occurs when less than mediocre developers only familiar with one approach apply those limited skills to a project that requires a completely different approach.

What the author describes is not "how PHP is supposed to work". It's just one of many ways PHP can work. (And certainly not my way of using it.)

Agreed. The big problem with PHP, as I see it, is that you have to be already very very good with PHP to write a safe, well-performing application in it. The steps you may take along the way to get there may be very scary, especially if it involves other people paying you to do it.

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.


2. Lack of architecture

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:


3. Frankenstein coding

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.

PHP sucks as a language, but honestly, it's a LOT less painful to develop a working web app in PHP than Java, Python, and just about everything else.

Why? There's no deployment issues. There's no waiting for my app server to restart, no delay while a change is detected, etc. You edit a file, click refresh.

Flame away.

PHP is fast to develop with, but its inconsistency and quirks make it a real PITA to work with quite often. a good summary of the main crap is outlined well at http://www.phpsadness.com/

Keep in mind that perhaps a majority of wordpress.org sites that have been around for a year or more have been hacked in some fashion at some point, and that the reason is because PHP encourages the kind of terrible code and unsafe-by-default environments that make this possible.

Edit For example, I am thinking of how various templating languages, including Jinja2 (for Python) default to auto-escaping strings you're echoing, but with PHP, you by default have to explicitly think about it and call `htmlentities($x, ENT_QUOTES, 'UTF-8')` all the time.

WordPress sites get hacked because the owner fails to update the platform or install 3rd party scripts/plugins without any sort of logical research.

This can be said about any platform, regardless of the language.

> WordPress sites get hacked because the owner fails to update the platform

Why are the updates even necessary? If you are still on Rails 2.3.8, you aren’t getting hacked just because you didn’t move to Rails 3 yet. But the situation with Wordpress & its ecosystem seems waaay less secure by default.

> This can be said about any platform, regardless of the language.

Not to the same degree, no sir.

Last time I checked Rails was not a content management system.

A fair comparison would be Drupal, Joomla, vBullentin - anything of that nature - which all regularly release updates.

Those are all PHP based and would seem to prove the point.

From TFA:

> * I have yet to see this kind of universal support for any other language than PHP. Not even Ruby on Rails, let alone Java, is available on mainstream providers, thereby validating the claim I made five years ago that Ruby on Rails won’t become mainstream (I regularly receive emails about this article asking me this question, and I keep responding “Nope, still not mainstream”).*

If your provider doesn't support Ruby, you need to get yourself a $20/month Linode box. If Linode and a $20/month price point isn't mainstream, I don't know what is.

How about NearlyFreeSpeech and other low cost solutions? I keep a forum for old friends, as an example. This is not worth 20 dollars a month for me. Hosting my own blog is not worth 20 dollars a month for me. (It's barely worth the two dollars a month I spend on it.)

I have a friend with a webcomic and an art gallery page. She doesn't need ruby on rails and a 20 dollar a month host. PHP is a nice solution for her.

That's why PHP is still around.

You can do cheaper than that - WebFaction will give you an $8 a month shared hosting account and you can run anything you want! They have a really cool automated setup system for more involved projects like Django/Pyramid/Sinatra/Rails and lots of others.

...which leads me to think that the poster is confusing "mainstream" with "GoDaddy".

Or confusing "mainstream" with "free webhosting by your internet provider"

I'm not.

I'm using a fairly "non-noob" ISP (ssh access, crontab, etc...) and they still don't give me access to much more than PHP. I can install Java but I can't even run it as a CGI because of the HTTP request memory constraints they impose. This is pretty standard, I don't blame them for doing this, and I would go with a VPS if actually needed all this.

Same for Ruby on Rails, obviously.

I fail to see why "my ISP doesn't give me Ruby" --> "Ruby isn't mainstream".

To my downvoter, here's a list of "mainstream" providers, at the Godaddy-level, and language support:

Dreamhost: RoR, PHP, Perl, Python [1]

Godaddy @ $8/month: PHP, Perl, Python, RoR [2]

a2Hosting @ $3/month: PHP, Perl, Ruby, Python

That seems pretty mainstream to me.

[1] http://beta.dreamhost.com/web-hosting/ [2] http://www.godaddy.com/hosting/web-hosting.aspx [3] http://www.a2hosting.com/services/web-hosting/

That's because clients rarely ask for it.

I work for an ISP and in about three years nobody had asked us about anything¹ more complicated than a simple PHP hosting with FTP access. (We don't really advertise hosting solutions, though, as this is not our main business.)

If you want your ISP to support something like Java or Rails — ask them today. They probably won't offer it now (or - who knows - they may surprise you!), but unless they're a type of company where individual client feedback gets lost, they'll note your request.


¹) Except for a colocated hosting, to be precise. But that's completely another case.

> "If your provider doesn't support Ruby, you need to get yourself a $20/month Linode box. If Linode and a $20/month price point isn't mainstream, I don't know what is."

True. And if nothing else, you can run Python on Google App Engine for free.

Also, Dreamhost's $8.95 a month shared hosting supports Ruby (via passenger).

>Either you like both or you don’t like either, there is no claim you can make about PHP that can’t be made about C as well

Except that PHP is terrible for systems programming?

And PHP has super-aggressive garbage collection and C has none. And C compiles to machine code and PHP compiles to optcode. And...wait a second, why are we comparing this two unrelated technologies again?

Is PHP that much worse where it's worth it to jump onto the ruby ship?

I'm just starting to code one of my current projects, but in PHP. Should I consider ruby instead?

Here is some PHP code:

$x = "0"; if(!$x){ echo "0 is false"; }

If you understand why it's crazy that PHP prints "0 is false" when you execute that, you're probably better off jumping ship now. If you don't, you'll probably appreciate the low barrier to entry for PHP more than any benefit you'd gain.

I understand why it prints zero is false, and personally I feel that it makes perfect sense. Indeed I approve of it. The fact that strings can be evaluated as numbers is great for accepting input from GET or POST because it means that there is no need to worry about explicitly casting strings to numbers.

Of course, input type validation is still important, and if a variable input by the user is supposed to be numeric, that is why there is the is_numeric() function to validate the type of a variable.

But once I've used is_numeric() and know that the string is numeric why should I bother with an explicit strtoint call? I feel that this feature of PHP if used correctly takes away complexity and repetition related to converting strings to integers.

In a realistic project the framework for your app should have a layer between user input and your code anyway. At this layer it will be validating that input from the user is of the correct type anyway, and once that variable passes the is_numeric() test the layer can easily cast that input string to an int so that it is the right type for JSON encoded objects or any other output from PHP for other languages that needs to have specific types.

Once again, if PHP is used properly, with a decent code architecture this feature of PHP is not a problem.

Perl does the same thing with type coercion, and "0" in Perl is false. However, the thing that Perl does that PHP doesn't is have different operators for strings and numbers.

Don't get me wrong, I think conflating strings and numbers is a bad idea, but if you're going to conflate strings and numbers, then having separate operators is the right thing to do.

I am not very familiar with Perl. When you say different operators for strings and numbers are you referring to something similar to PHP's === operator for which "1"===true would be a false statement?

Perl's numeric equivalence operator is ==, while its string equality operator is eq. Perl's operators are monomorphic that way.

in perl

"==" returns true if the left argument is numerically equal to the right argument.

"eq" returns true if the left argument is stringwise equal to the right argument.

see 'perldoc perlop' under the heading "Equality Operators"

I understand the standpoint of people thinking it's crazy. But javascript does the same thing, does it not?

I thought this is what the triple equals is for?

Yes Javascript does it too, and it's considered one of its top warts for the same reason. The tl;dr version is: always use triple equals, never double.

Actually, here's a more insane version:

  $x = 0;


    echo '"0" is empty';


empty() is an alias for 'isset($x) && $x', so this example is semantically identical to the previous one (since $x is always set). PHP doesn't have any special concept of "emptyness" to check for.

I submit that PHP's popularity has much more to do with mod_php and its ubiquity across cheap web hosts than any intrinsic merits as a language.

As someone who made a good living for many years by building stuff with PHP... I couldn't get away from it fast enough. Rails+Heroku is the new PHP, if you want a batteries-included web framework and easy hosting.

Not rhetorical: does anyone here use PHP for starting new projects?

Yes, in fact all of my new projects are in PHP unless I'm absolutely forced to use something else (and I say this as someone with years of Java experience and some Ruby experience).

"there is no claim you can make about PHP that can’t be made about C as well, and vice versa."

What about hundreds or thousands of inconsistently named built-in functions?

C doesn't really have built-in functions, just a standard library that you don't have to load if you don't like it.

That's at best semantic nit-picking. You cannot write a useful C program without using the standard library or re-implementing (parts of) its functionality yourself. If for some reason having functions available that you don't use bothers you, you can still easily disable most of them by not loading any extensions; and if it's really a big issue to have the 'standard' functions in php available, you can compile php to not include them. If this is the best example of why php isn't like C, they are actually very similar...

The core of C is small enough that you can fit it in your head.

PHP has so many functions that it's almost impossible to write it without googling php.net, etc.

Not that this matters so much, Google is fast and omnipresent, but in that sense they are definitively not alike.

Almost impossible? Pop quiz: The case-insensitive version of "strpos" is "stripos", what is the case-insensitive version of "strcmp"?

I'm guessing it's stricmp... However off the top of my head I have absolutely no idea what the argument order and return values for any of those four functions will be without looking them up.

buzzer sound I'm sorry, the answer we were looking for was "strcasecmp"

(Sorry if the level of levity is considered inappropriate, but humour is a level 4 defence mechanism and the only way I can remain sane in the face of such things)

> Not even Ruby on Rails, let alone Java, is available on mainstream providers

Just picking a few of the "big" ones:

dreamhost.com: supports RoR

hostgator.com: supports RoR

bluehost.com: supports ROR

hostmonster.com: supports RoR

godaddy.com: partially supports RoR (fastcgi)

I guess that is simply not true anymore

One of the reasons I like PHP is that it still lets you get to a lower level of coding. Many of the newer languages and frameworks that have become popular in the past couple of years abstract things such as database connectivity away (Django is a good example of this) and it makes it difficult to optimize queries effectively without hacking onto the framework.

Rails has two ways to do this. You can do any select query returning active record objects with

    Model.find_by_sql("raw select query")
And any query with a driver dependent result using

    ActiveRecord::Base.connection.execute("raw sql")
You can shorten the second one to simply "execute" by creating a method to wrap the functionality.

Don't confuse abstraction and formalization with convention with restricting low-level access. Most ORM frameworks allow you to drop down to direct SQL if you need to.

Most ORMs (including Django) let you easily drop-down into writing your own custom SQL queries when the need arises.

I've used Django and many others and while you can do this, you end up with code that isn't very clean.

Depends on your definition of 'clean'. I think Django found a very solid way to handle raw SQL statements[0].

[0] https://docs.djangoproject.com/en/dev/topics/db/sql/

Wow, It's pretty apparent that there are a lot of young programmers here on HN. I was just stating my opinion and I got downvoted because I talked bad about your precious frameworks.

The comparison between PHP and frameworks isn't valid. Writing PHP on a framework probably abstracts away SQL too, just like writing CGI in Python gives you lower-level control.

When frameworks are the popular alternative to PHP (RoR,Django,etc), it is valid.

Are we also not allowed to talk about RoR when it comes to a discussion about PHP alternatives?

That is like saying Cocoa is a popular alternative to C++, but you prefer C++ because it allows you to write your own UI event loop.

I guess it is true if you really stretch your imagination, but does it mean anything?

Yes, when I write a web app, I don't want to be stuck with extra code that abstracts away the database into a less-efficient object/class and forces me to break the convention of the framework to write the code that I need.

I suppose it's fine when many of then newer programmers don't even know or understand what's going on underneath anyway...

It's a bit comparing apples to oranges. If you were comparing say Cake or Zend to RoR and Django then it would be a reasonable comparison.

It's not really apples and oranges - writing a website in raw Ruby is not a very feasible or popular option, whereas writing a website in raw PHP is. It is valid to compare writing a site in PHP and writing a website in Rails. It is also valid to compare writing one in Cake vs. RoR, as well as Cake vs. raw PHP (or a custom PHP framework, which is what raw PHP inevitably becomes in a sufficiently large project).

It doesn't stop the hordes of programmers on HN talking about Ror and Django and Cherry pi as an alternative to PHP.

guess what? You aren't going to stop me from my opinion, sorry. You sure as hell aren't stopping the mass amounts of people from down voting my above comments for merely stating my opinion on frameworks.

oh and btw, my point has pretty much been proven.

Feel as righteous as you want, but bitching that you got downvoted and nobody explained and then accusing random downvotes of being young amateurs is indeed boring fucking reading.

Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact