public

In which I do a little digging about the choices I've made with PHP. This is a long read, but it isn't something that can be explained in one or two paragraphs.

  • Download Gist
blog - Explaining My Choices Further.md
Markdown

In the comments from my last post and on Twitter I noticed a lot of people who had something to say about PHP. The comments were varied but they usally sounded something like this (sorry @ipetepete, I picked yours because it was the shortest).

...the little bits of soul from all of us who've had to work on, and or maintain large PHP applications. – ipetepete

In Pete's defense, he did go on to say that rest of the stack I was using was a "smorgasbord of awesome". Thanks, Pete. I agree!

I would, however, like to take a little time to correct a misperception in the developer community about PHP. I recently got into this same... discussion... with Jeff Atwood, and I seem to be running into it more and more. So here goes. Please bear with me as I cover a little history further on.

Pete, and everybody else, you're exactly right. There are a frightening number of PHP applications out there that are just awful. Awful, awful, awful. At my previous job I inherited a custom PHP ecommerce site that was absolutely foaming at the mouth with technical debt. We're talking the Nile River of procedural code here. Even after a solid year of working on it and modernizing the code base, I still wouldn't call it a "good" application. Its good enough to not get hacked into oblivion now, basically. And that was with a year of dedicated effort!

I think all of us that have worked with or even touched PHP can tell some variation of this story. Multiply those horror stories out across tens of thousands of developers and then toss in this lovely mix of terror: Wordpress, PHPBB, osCommerce, Magento, the list goes on... and on... and on... and ON.

Is it any wonder that developers have this knee jerk reaction to PHP as some sort of torture device that sucks two or three years of their career down the drain as they futilely attempt to keep some ancient, crumbling relic of a code base on life support? The 2000's are littered with the remains of open-source projects and applications that are a testament to the wild, untamed nature of PHP. At a previous job I had a client call and request that we redo part of her Magento web site and I literally got a sick feeling in the pit of my stomach.

When you look at it from that perspective, reactions like Pete's are perfectly normal! Nothing to argue about here; move along, move along.

A little history & a revolution

PHP didn't even start to see "frameworks" emerge until 2005 (the earliest references I can find of the Zend Framework are back in 2005, although the first stable production release wasn't until 2007). Symfony 1 didn't get started until 2005. Even then there was zero interoperability. My knowledge of Joomla's framework didn't carry over into other frameworks because there wasn't any shared code. The whole while, swarms of people were endlessly reinventing the same rusty, broken wheel over and over again.

The Visigoths never invaded, in the Ruby world. While the PHP world was desperately trying to convince people to even use what fledgling frameworks there were, the Ruby community was inventing Gems (2003), Rails (also 2003), Rack (2007), and other great tools.

PHP didn't see its first real package manager, Composer, until late 2011. Since then, there's been an explosion of packages available for PHP. It isn't a fad - the statistics speak for themselves. 10,000 packages available. Nearly 20 million packages installed since this time last year. Things are changing rapidly. The Composer package manager might be the most revolutionary tool ever released for PHP.

You might be wondering where I'm going with this. Fair enough.

A little code

It is not 2007 for PHP anymore. There has been a significant change in the community - a revolution toward shared code and interoperability. We took the achivements that had been so thoroughly demonstrated by the Node and Ruby communities and latched on as tightly as we could. PHP Frameworks are sharing libraries. Standard tools are proliferating. Unit and behavior testing is being evangelized.

The days when programmers opened up a blank file, named it index.php, and said, "time to start coding!" are over. Projects are modular, and web applications are following the RESTful principles that Rails brought. I look at code from a Symfony 2 project and a Rails project and I see the exact same principles at play.

Here's an example controller action from the excellent Discourse project, written in Ruby for the Rails framework.

class TopicsController < ApplicationController

    #....

    def star
        @topic = Topic.where(id: params[:topic_id].to_i).first
        guardian.ensure_can_see!(@topic)

        @topic.toggle_star(current_user, params[:starred] == 'true')
        render nothing: true
    end

Here is my (rough) interpretation of how I would write this same action in PHP for the Symfony framework.

<?php

class TopicsController extends Controller
{
    //....

    public function star($topic_id, $starred)
    {
        $topic = $this->get('model.Topic')->find($topic_id);

        $this->get('guardian')->ensureVisible($topic);

        $topic->toggleStar($this->getUser(), $starred);

        return; //I would usually return a status code here, depending on success/failure
    }
}

Not that different, really. In both cases I see clean, maintainable code. There are some differences in how Symfony manages classes through its service container that make it a little more involved, but only just, and those are really a matter of preference. I could install a library that makes the code look almost 1:1.

Some stats

I have two applications that are in what I would consider "maintenance" mode (only bug fixes and minor improvements, no new features). One is Rails, the other is Symfony. Both are coded exceptionally well. I did not originally code either of them. I ran some Fogbugz reports and came up with the following.

  • I spend more time managing and fixing my PHP code than I do Ruby code. About 2x as much.
  • I spend more time managing how Ruby runs (configuration, deployment, versions, gems, etc.). About 2x as much as I do PHP.

I was a little surprised at how close the numbers were. It feels like I spend more time working on the PHP app but it really comes out as a wash when I factor in all the time I have to spend twiddling with the server for the Ruby app. (In Ruby's defense - this process gets easier and easier all the time.)

It turns out that the language doesn't matter - the technical debt is the same, either way. Almost zero.

Developers everywhere - PHP is not the same as it was even two years ago. Stop acting like it. The language and the community have both changed significantly. In many ways PHP is just now starting to come into its own. In many ways, the PHP community has gone back in time - back to relive the days that should have been spent building the tools and libraries that were never built. Another Magento is not going to appear. It will not happen. Stop worrying about it.

If we do see another wildly popular open source project emerge from the PHP world (and I firmly believe that we will) it will look far more akin to a project like Discourse. Clean, well structured, maintanable code.

Jeff Atwood has stated publicly that one of his ulterior motives with the Discourse project is get people to stop using PHP and start using Ruby. I like Jeff Atwood and respect his opinions but I truly believe he's speaking in ignorance here. He and many others look at the source code for projects like Wordpress (which has been around since 2003), recoil in horror, and feel like they're doing the wider community a service by making declaring a religious war against PHP.

If PHP hadn't evolved, Jeff, I would be right there next to you, carrying that banner.

But it has.

Oh, but it hasn't. We might have gotten some additional layers of abstraction smeared on top of the PHP stack, but the standard library is still the old nasty mess of inconsistent APIs, no namespacing and legacy crap from 1998. The mere existence of crap like the readfile() function is a testament to this.

Oh, and while the OOP stuff in PHP has gotten better, the syntax and implementation still makes very clear the fact that PHP was not designed for OOP. The new namespacing stuff is so confusing that you're pretty much forced to use an IDE when working with it to make sense of what scope you're in.

Jarrod, I couldn't agree with you more. I was one of the early adopters of the Zend Framework and have been using it since the 0.4 version. It has taught me a ton about coding standards, design pattern implementation and managing complexity.

I think PHP is mostly about community. People may complain about the language, and it isn't pretty, but it gets the job done. It's the community that builds great tooling and follows them with passion that makes PHP such an attractive environment to work with. PHP still dwarfs all of the other web languages as far as adoption and community is concerned - and that's a good thing. Thanks you for writing this post, it's awesome.

Agree complete Jarrod, very good post.

@miki, please tell me how a namespace declaration at the top of a file is in any way confusing. Namespace support in PHP is a kludge of syntactic sugar, in no way should that force anyone to use an IDE.

wait till they code in laravel

I agree with a lot of this post, but I think it overlooks a lot of the history. PHP has been moving in this direction for a long time. Composer is great, but it is building on concepts borrowed from gems and PEAR. PEAR was the first widely adopted attempt at building reusable PHP components. PECL did the same for non core C extensions to PHP.

PHP is far from perfect, but it makes it pretty easy to get the job done. bash isn't pretty either, but you'll be hard pressed to find a *nix sys admin who doesn't rely on it daily. PHP is just another tool that one can keep in their toolbox.

I totally agree. Although I do believe that Php, from a syntactic point of view, is behind its main competitors, I always found critics to it very naive, and based to ridicously obsolete code examples (see Atwood and his mentions to Wordpress).

What feeds this feeling against php is that the most famous php projects are written in a bad and old legacy php code (wordpress, phpbb, mediawiki). But there are already a lot of wonderful alternatives to many of them!

PHP's community may have improved, but PHP still is a poorly thought out language. There's just too many horrible mistakes that need to be maintained for the sake of backwards compatibility. There have been those who tried to fix it, but they're consistently beaten down with a shovel.

PHP is, and always will be, one huge hack.

Ruby, on the other hand, is highly consistent, and follows a few simple (and intuitive) logical rules.

Nice post, kind of annoyed by how many are bashing PHP out there.

"Back in the day" my choice was Java, PHP or ASP. Visual basic was just horrible (multiline comments? not possible). Java needed huge amounts of server-side software and a computer-science degree just to get Hello World up. PHP was made for web-development.

When internet-usage exploded, so did the numbers of developers. There wasn't much education options for webdevs, and we got a lot of sub-par code. But the net survived, it even continued to grow.

Now I'm working the frontend-side, and I've heard rumours that Javascript is not perfect either (wat!), but somehow it's widely used anyway.

As Dave H says: PEAR was clearly out and about, and I'd suggest earlier than Gems/Rails/etc. What was clearly lacking, unlike perl's CPAN the concept of a centralised repository did not work well enough.

It took a substantial amount of time for hosting solutions like github to become feasible for any but highly skilled developers who could run their own SVN servers, or use google code/sourceforge/etc as time moved on.

The root cause of the problem: What passed for reusable components then also relied on centralised control over scarce resources. This meant that if you had an idea, you had to achieve consensus that it was a good idea or go find resources elsewhere.
Accordingly, there's a lot of PHP code in the wild which grew out of a concept, and has been refactored to be reusable that can now lean on a framework if they so choose - but when initially presented to a group probably seemed trivial or poorly thought out (thus faced a high barrier to acceptance).

Frankly, who cares: people use 'just enough' of a tool to solve a problem and evolve their understanding to meet.

"""PHP's community may have improved, but PHP still is a poorly thought out language. There's just too many horrible mistakes that need to be maintained for the sake of backwards compatibility."""

So what? What language doesn't have that?

You learn to code around those, and you move along.

How is Javascript, the current darling, much better?

There's just too much bad blood with PHP for it to ever recover. Languages simply don't last once they're at this level (look at Perl, or Smalltalk) so the writing is on the wall. Even if PHP were the best web language, that's not enough anymore with the web becoming less dominant by the day (compared to mobile, native, devops, science, and all the other domains people program in).

Python is strong in many disciplines, Java/Objective-C are the perfect languages for their respective platforms, Go is powerful for systems work, etc... There's just no need for a web-only language anymore even if it can be shoehorned into other spaces.

My advice is to quit while you're ahead and get on Python, Go, Haskell, Lua, Objective-C, Java, whatever.

Now, with that said, PHP has a large enough install base that you could not learn another language for the rest of your working life and still have work to do - but that seems incredibly boring and it you will be working on the oldest, most depressing codebases.

"If we do see another wildly popular open source project emerge from the PHP world "

How about WordPress? Certainly not written to the highest standards of PHP development, but it could be considered "wildly popular".

@conatus
Wordpress is successfull because of it's very good UI and it's features most of other blog engines dont even offer.

But Wordpress code is a disaster from a engineering perspective , and makes it very unsecure. (especially the plugin system ).

Wordpress works on a large number of host since it supports old PHP versions , so it will always be the engine of choice for non technical people.

@adamn, I couldn't help think of Cobol after reading your post.

"PHP was not designed for OOP", but LISP wasn't either. OOP has never been, and will never be, a substitute for first-class functions. OOP is just one particular way of using first-class functions and definitely not the only valid one. Really, none of the popular, contemporary design principles, such as OOP, should be treated as goals in themselves.

For example:

$topic = $this->get('model.Topic')->find($topic_id);

There may be a justification for this lengthy incantation, but it is certainly not clear from the example or from the paucity of context mentioned, that it makes sense to do that.

The practice of hiding functions in the result of another function call, in order to seek a polymorphic effect, may make sense, yes, but it really needs to be justified. Otherwise, it makes much more sense to implement the simplest possible incarnation:

$topic = findTopic($topic_id);

Or, if the idea is to have one function handling all lookups by primary key:

$topic = findByPrimaryKey('topic',$topic_id);

Some people misunderstand the process, though. They think that by starting from a complex framework, and by using convoluted incantations from the get-go, they will end up with a successful application. This has never happened and will never happen. First you need to solve a real problem. Unfortunately, that has in itself nothing to do with using length object expressions in your code. On the contrary, doing that for no good reason at all, will divert the attention away from what really matters.

MediaWiki, Wordpress and Drupal use neither OOP (nor MVC) as core design principles because the overruling concern in their application space is pluggability.

Neither OOP nor MVC contribute anything at all to the issue of application pluggability. That is why hardly any of the "beautifully-designed" Ruby programs come with a plugin repository filled with extensions contributed by external developers. That is how "beautifully-designed" these programs are ;-)

Bu then again, I do not deny that more complex data structures and polymorphic functions may eventually emerge from a successful application that, over time, gradually gets re-factored in order to solve particular problems more elegantly. MediaWiki is actually a good example of this approach. By the way, MediaWiki has a massive plugin repository with quite a few popular extensions contributed by third-party developers.

"...smeared on top of the PHP stack, but the standard library is still the old nasty mess of inconsistent APIs, no namespacing and legacy crap from 1998..."

Well, all applications, on any modern system, route their system calls through the notorious libc, which is indeed also an old nasty mess of inconsistent APIs, no namespacing, and horrible legacy crap from 1969-1973. How dare they use this horror, even in the newest IPhone, IPad, and Android systems? ;-)
Shouldn't they be using Symphony2 instead? ;-)

It's not even worth the discussion most of the time. Die-hard ruby enthusiasts are just as bad as die-hard php enthusiasts. In the world of development you are either successfully writing, shipping and maintaining good code or you are not. The language does not dictate how you use it and never will - only the skills of the developer formulate those laws. There are naive people all over the world writing god-awful code in every language so there's really no point in debating the merits of the language itself. Every language can offer database connectivity, routing, form posting and other necessities. One man's readfile is another man's

File.open("my/file/path", "r").each_line do |line|

At the end of the day every language can produce an example project that is better than 95% of the projects in another language. It's all just syntax surrounded by a whole lot of useless posturing.

Having started PHP in 2004 (I was 16 at the time, so not a lot of experience on anything else), it led me to build my own framework and always start websites with that same base. But obviously, having learnt it by myself, I was lacking a lot of best practices. But everything was working well enough for me not to feel the need of looking anywhere else (frameworks or other languages).

It bit me a few years later when I started thinking about being a developer for real. I basically rejected all compiled languages and decided to change this. I wrote a post about how PHP ruined my life as a software developer

I'm now working in Python, and I'm very happy about it. Using Django as a framework and AngularJS on top of it, makes me love to code again!

Good article @albandum. The biggest problem PHP has is that it lets you do horrible things without immediate punishment. It's harder to write bad code in the "real" scripting languages out there because you are immediately bitten on the ass by your piss poor design choices.

PHP lets you write the worlds shittiest code and only stops working correctly when it's too late to change it. And even then, you can generally just hack your way back on track and never learn a damn thing about actual software design. And on the internet, one mans hacked together security nightmare becomes the worlds most popular CMS.

I love PHP. It's powerful and can do damn near anything you need it to, but if you're learning by yourself, it allows you to pick up toxic habits. I would never advise someone pick up PHP as a first language.

It's too dangerous to use unsupervised if you're just getting started.

@paul-vg I haven't written any PHP code in a while, last time being before namespaces were introduced. I decided to look at them to see how they were implemented, and I have to say, in my opinion, it's messy and overly complicated. Here are the main things I see as problems (in my opinion):

  • You can split namespaces over multiple files. I think by the time you need to split out a namespace, you need to reconsider why that namespace got so big, and think of ways to better separate your code.

  • You can declare multiple namespaces in a file. Then they tell you right after telling you that, they say "It is strongly discouraged as a coding practice to combine multiple namespaces into the same file.". Then why let you do it?

  • You can put global namespace code in a namespace file. That just seems like it'll lead to confusion down the road. Really, it would have vastly simplified the whole thing if they just stuck to 1 namespace per file. Some code is running on the global namespace and you have no idea what file it's in.

  • Functions and constants will resolve to the same namespace that it's in, if it's declared, but resolve to global otherwise. But where do variables resolve to? This inconsistent resolution gets confusing, and forces you to know all the prior declarations in the file to know where it will resolve to. There are more rules on top of that that makes resolution far more complicated than it needs to be.

Because of the complex namespace resolution rules, I agree with @mikl. In order to properly keep track of what is calling what in a sufficiently large and complex codebase, you need an IDE to keep track of where the namespace accesses will resolve to. Most scripting languages simply load modules as an object, and after that you just treat them like objects. From what I just read, the PHP namespace syntax is unnecessary, the resolution complex, and the entire concept messy.

I haven't read your whole post but what the heck is your problem with Magento? It's one of the best written PHP software I've ever seen. It's nowhere close to crap like Wordpress, PHPBB and osCommerce. It might have some complex concepts with you have to understand but that's a problem software written in any language could have and not the same problem as WP and others suffer from. It's one of those software I love working with and it blows my mind how customizable it is.

I see critics of the PHP critics around here miss one very important point: you cannot simply say "PHP has evolved" and upgrade, rewrite or remove all the messy and incredibly hard to maintain projects around the world with one wave of a magic wand.

Having better syntactic sugar and a package manager doesn't help the firms with PHP websites written in 5 frameworks and being 10,000+ lines big to evolve their projects.

PHP has evolved. Fine. Upgrading your old project VPS' PHP version to 5.5 and using your finally ready package manager won't change a thing. Making your application evolution 2% faster because of new language features doesn't change a thing.

Having alternatives to the old mammoth frameworks doesn't change a thing either -- do you have a migration tool which can translate a mix of PrestaShop, WordPress, Zend and Symfony 1.3.* project to a fantastic new PHP framework? No.

I agree with @adamn -- languages making it to this step won't see any further adoption. On the contrary, its adoption is already starting to decline. I made good few thousands bucks by rewriting several projects from PHP monster mixes of "frameworks" to Rails or Node. And people were grateful and were paying good money for it.

So, evolution you say. But in my eyes, it's too little and too late. No hard feelings.

I agree entirely, but I'd put the transition back even further. I'd say the evolution to a grown-up language and ecosystem began back in 2004 with the release of PHP 5. I traced that evolution in my NYC Camp keynote back in July, too.

Video here: http://drupaltv.org/video/nyc-camp-2013-keynote-larry-garfield
Slides here: http://garfieldtech.com/presentations/nyccamp2013-php-pie

PHP is a very different language and ecosystem than most people remember. Yeah, there's still a lot of legacy code out there but you know what? It's not going to be any cheaper to rewrite it from scratch in some new-wave hipster language than it is to rewrite in modern PHP, and you may be able to salvage some pieces of it, too. Or at least reuse the same development skills. If you're paying for a ground-up rewrite, you may as well ground-up rewrite in modern PHP for less than rewriting in non-PHP.

For all of those saying it's too late for good things to happen to PHP... Nobody in the web dev field used Ruby until Rails happened. And Rails happened a mere 10 years after the language was released in 1995. So I wouldn't really make any grandiose claims :)

(OK so I might be exaggerating by saying "nobody" but you get the point I hope)

I would even take the extra step and claim that PHP has its brightest days ahead. Yes, I am biased, I've been developing in PHP for 8 years now and I started with the horrible practices of mixing HTML output with logic, I made a lot of unsecured websites back when I didn't know what escaping was. But in order to survive and become competitive, developers have to establish a common coding standard, organize and reuse their code properly and make tools that simplify automation for continuous integration, running tests and deployment.

We now have all that in PHP community and we are able to develop projects with maintainable and unit-tested code.

The next big thing are reactive applications. PHP was designed to generate HTML output and die, but it's now being used for longrunning processes. This approach has its disadvantages and you have to be careful, but it's doable. You can even write your own HTTP server in PHP if you have some special needs and not being able to write Apache module or something like that. Why? Because why not? Although there are better tools for that, familiarity of the language and unified codebase simplify everything.

Once that popularity of ReactPHP and similar libraries rises, people will demand improvement of the language to handle these use cases better. And it will get better.

@mikl

readfile()? Well you would use

new SplFileObject($file)->fpassthru();

Do you expect them to remove readfile()? Then you would complain PHP always breaks backwards compatibility.

In my general day-to-day work my goal isn't to produce code; it's to solve problems. A majority of languages seem to produce lots of frameworks, utility libraries and single-purpose applications. I have much love for projects like Redmine, Solr, Hibernate, Twistd, etc. but they are either too narrow in scope for me to solve different problems with or they're frameworks and libraries that make things easier but still require me to spend a lot of time writing admin forms and menus. I chalk it up to the low barrier to entry, but PHP has produced arguably three of the most popular and widely supported open-source content management platforms. Not saying that any of them are good in terms of code quality, but they allow me to solve certain classes of problems better than anything else while not driving me entirely insane. If I had unlimited time and budget to get it right and it didn't need to altered by anyone else after I was done would I use WordPress or Joomla or Drupal? No. Would I use PHP? Probably not. But I don't have that job and my free time is similarly constrained.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.