Skip to content

Instantly share code, notes, and snippets.

Last active April 25, 2023 19:31
Show Gist options
  • Save Blackshawk/5327505 to your computer and use it in GitHub Desktop.
Save Blackshawk/5327505 to your computer and use it in GitHub Desktop.
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.

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
        @topic.toggle_star(current_user, params[:starred] == 'true')
        render nothing: true

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


class TopicsController extends Controller

    public function star($topic_id, $starred)
        $topic = $this->get('model.Topic')->find($topic_id);
        $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.

Copy link

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.

Copy link

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

Copy link

"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? ;-)

Copy link

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"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.

Copy link

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!

Copy link

WMeldon commented Aug 24, 2013

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.

Copy link

etler commented Aug 24, 2013

@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.

Copy link

celmaun commented Aug 24, 2013

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.

Copy link

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.

Copy link

Crell commented Aug 24, 2013

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:
Slides here:

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.

Copy link

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)

Copy link

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.

Copy link

gsdevme commented Aug 27, 2013


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.

Copy link

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.

Copy link

I've only been developing with PHP for about a year, so forgive me if I'm being naive but surely, regardless of the language, we're building software to solve problems, a lot of the time for people who simply don't care how it's done, they just want it to work. So in that respect, the likes of Magento and WordPress are perfect solutions to their respective problems, regardless of whether they follow best practices to the letter...

I'm a big fan of PHP, perhaps because of it's forgiving nature. Whatever it is, it allows me to get the job done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment