rc3.org

Strong opinions, weakly held

Tag: PHP

PHP’s hidden strength

It’s easy to complain about PHP. Look, here’s Jeff Atwood complaining about PHP. He proposes to create something that will replace PHP. I’m all for this project — as an industry, we should constantly be working to improve and replace things, and we should be building great things in case they do wind up becoming popular.

If you’re going to try to replace PHP, you need to figure out what it is about PHP that enables it to maintain its massive market share. Everybody knows about the friendly learning curve and the easy availability of inexpensive hosting. If you want to create your first Web application, PHP is the simplest way to get started.

What’s interesting, though, are the reasons why you see some of the biggest Web sites deployed on PHP. It’s not because developers love it. It starts with the fact that PHP is easy to operationalize at any scale, or at least easier than most other technologies. It doesn’t require an app server, or a virtual machine, or anything that’s outside the realm of basic Unix processes.

What’s more important, though, is that many of the most experienced ops people in the industry who have deployed large scale sites have a PHP background. They understand how PHP works and where it fails. Building that experience on a different stack would take the same thousands of hours that they’ve already invested in learning how PHP scales. It also seems to me that you see less scaling-related drama from PHP-based sites than you see with sites that try newer technologies, or eclectic mixes of technologies. We’ve never seen Facebook go through growing pains like Twitter has gone through.

If you’re working on something with the goal of displacing PHP, the Twelve-Factor App manifesto is not a bad place to start. The other option is to build something that runs on top of the JVM, because there’s a lot of operational expertise in that area as well.

That said, the simplicity of PHP from an operations standpoint and the deep experience with it will make it somewhat difficult to displace PHP from its current position in the industry, no matter how much programmers like to gripe about it.

How do you run SSH from a PHP script?

I’m writing a very simple deployment script that logs into a remote server and uses Git to pull the latest code from the remote repository. The deployment application runs on Server A, and it will update code on Server B and Server C.

The deployment application is written in PHP, and it’s easy enough to call the ssh command using PHP’s shell_exec() function. Well, calling SSH is easy, but making it work is a bit more difficult.

SSH really wants to run as a user who has a .ssh directory in their home directory. First, it needs to find the private key in order to authenticate against the remote server. You can get around that using the -i flag and pointing at a specific key file. You also need to indicate to SSH that you don’t care about the host key (which prevents you from being victimized by man-in-the-middle attacks) or to point it to your known_hosts file. You can specify a custom location for that using the -o option, like this:

-o UserKnownHostsFile=keys/known_hosts

Even after that, though, SSH still insists on using a .ssh directory for the user running the command, in this case, the Apache user. Creating such a folder doesn’t seem like it should be necessary, but I haven’t been able to figure out how to avoid it.

If I can’t get this to work, I could try using the SSH2 library for PHP, but I’d prefer not to, since I don’t want to deal with the added dependency.

I’ve posted this question on Stack Overflow as well.

Building distributable Web applications

My current project involves building a commercial Java Web application. For years I’ve built Web applications (using Java and a number of other platforms) to deploy on our own servers. Building something that’s suitable for distribution is a horse of a different color. I thought I’d write up my experiences for other people who are taking on similar tasks.

  • Distribution format – Usually Java applications are distributed as WAR or EAR files, but many people also package their Java Web applications with a servlet container to run them to make things easier.
  • Open source licenses – My application uses a number of open source libraries, and I had to go through and make sure that all of the libraries were distributable without much fuss.
  • Configuration – What’s the best way to set up database connections and other configuration parameters?
  • Deployment platform – In theory, Java Web applications should work with any servlet container, but the devil is always in the details. Many Java applications seem to be distributed with a servlet container as well. What’s the best approach?

Look for separate posts dealing with each of those issues.

I’m sure other considerations will arise as well, but those are the first few that have cropped up as I’ve started working on this.

Embarking on this process makes it clear why PHP has become the dominant platform for writing distributable Web applications. Regardless of its strengths and weaknesses as a development platform, its deployment story is hard to beat.

There are no real questions when it comes to distribution format. You archive the files and put them up for download. The end user downloads the archive, expands it, and puts the files in the directory where they want the application to appear.

As far as licenses go, many PHP applications have no external dependencies. PHP provides all of the functionality you need for most applications, and PHP developers have never really taken to using libraries to make things easier. Java developers tend to use tons of third party libraries, and Ruby on Rails applications often depend on dozens of Gems. PHP developers use what’s available as part of PHP and that’s it. PEAR is out there, but it isn’t terribly popular. I assume that’s because so many PHP applications are deployed on shared hosting. It’s just not worth the risk to bring in dependencies if you don’t have to.

Configuring a PHP application usually involves editing one heavily commented PHP file. Most people consider that to be inelegant, but it’s hard to argue with the simplicity.

PHP is ubiquitous, so there’s not much to worry about in terms of deployment. You just need Apache with PHP support.

When you look at those factors as compared to Java or Ruby, it’s easy to see why PHP maintains its massive popularity over other development platforms, and why we see explosive growth among applications built using PHP, like Drupal, WordPress, and MediaWiki. For all its drawbacks, PHP has evolved in a world where simple deployment and configuration are both hugely important, and that has given PHP some powerful advantages that other platforms aren’t even trying to compete with.

HipHop is an accelerator for PHP from Facebook

Today I’m excited to share the project a small team of amazing people and I have been working on for the past two years; HipHop for PHP. With HipHop we’ve reduced the CPU usage on our Web servers on average by about fifty percent, depending on the page. Less CPU means fewer servers, which means less overhead. This project has had a tremendous impact on Facebook. We feel the Web at large can benefit from HipHop, so we are releasing it as open source this evening in hope that it brings a new focus toward scaling large complex websites with PHP.

Facebook developer Haiping Zhao announces HipHop for PHP, a tool that translates PHP to C++ and compiles it using g++.

Storing data for Google Maps

I hinted at this in my link post, but I thought I’d write up the whole thing in hopes of discussing it. I have a page that will include a Google Map with markers for a number of locations (potentially a large number of markers). For an explanation of how to add markers to a Google Map, check out this page.

So the question is: how do you get the address data from my database to Google Maps?

The process is to geocode the address and then apply the marker to the map. There’s a simple example at that link.

Here are some possible approaches:

  1. Write some code (PHP in this case) that emits the JavaScript used to geocode the addresses and put the markers on the map. Unfortunately then you have a mixture of JavaScript and PHP code that looks a lot like JavaScript on your page.
  2. Print out a JavaScript data structure that contains all the information for the markers and then iterate over that data structure in JavaScript.
  3. Put the map data in hidden elements on the page where it can be extracted using JavaScript. The downside is you have hidden elements on your page. The upside is that your PHP is completely separated from your JavaScript.
  4. Create a service that returns a JSON data structure of the marker information that can be called using XmlHttpRequest and call that from the page. That offers a clean separation of the JavaScript from the PHP but unfortunately could add latency to the page.

I’ve done some searching to find out how people handle this problem, but haven’t seen any good answers yet. Any ideas?

Links for August 25

  • Glenn Greenwald on what all Americans should know about the 2004 CIA Inspector General’s report that was released on Monday.
  • Alex Tabarrok (the more doctrinaire libertarian half of the team at Marginal Revolution) explains why you must have a public option if health care reform will include an individual mandate. Further proof that I was completely wrong in arguing that the public option is not necessary.
  • Spencer Ackerman explains the insidiousness of torture — once you’ve embarked on a program of torture, the logical response to not getting the information you expect is to order more torture.
  • If you’re trying to embed Google Maps in your Web site and want to start with a centered map of the United States, Lebanon, Kansas is the spot.
  • Today I was trying to come up with good ways to avoid mixing JavaScript code with PHP code. Here’s a Stack Overflow question on the topic. I almost wonder whether using AJAX is better than writing PHP that emits JavaScript.

Why do Ruby developers test?

Giant Robots asks the question, Why Do Rubyists Test So Completely? It’s a good question. Developers on other platforms would benefit greatly from the culture of testing that has been established among Rubyists (and especially Rails developers). They have their own list, and I agree with all of the items on it. I have one reason that I’m surprised they didn’t list.

Rails makes it really easy to start testing. When you generate a new Rails application, it gives you a place to put your tests. When you generate controllers and models, it creates skeletal tests for them. Nobody has to sit and wonder, “What should I be testing.” The framework tells you. So the next step is just to fill in the blanks. Then when you want to run your tests, you just type “rake” in your application directory.

Java has JUnit and all of the IDEs have test runners, but beyond that, you’re on your own. What do you test? How do you organize your tests into suites? How do you run the suites? These are all questions you have to answer before you build a testing regime. Individual unit tests are easy to write, but getting it together to really make a habit of testing is a lot more work than it is with Rails.

And in the PHP world, things are even worse. I have never seen a PHP application with a robust unit test suite, although I’m sure they exist.

The Rails approach makes the biggest difference with people who aren’t already committed to unit testing. If you know the value of testing, you’ll jump through the hoops to set up tests, even if it’s a pain. If you’re not yet convinced, then the extra work required to set up unit testing with other platforms prevents people from getting started. It’s very much the deliberate choices the creators of Rails made to encourage and facilitate testing that explain in large part why testing is such a part of the culture.

PHP Frameworks, a series of last straws

Over the past couple of days, I’ve been looking at PHP frameworks for a project. I’ve dug into the PHP MVC world any number of times, and have even used a couple of these frameworks before, but I’ve never been really satisfied with any of them. I’d make a table comparing them, or something, but that’s not really how I work.

Generally, the way I evaluate software is that I just pick something and start using it until I run into a problem that I am not willing to accept or work around, then I move on to something else. Sometimes it takes an hour, sometimes a single project, and sometimes it takes years, but the methodology never changes.

Here’s how it went.

Zend

This time around, I started with the Zend Framework. Why? It’s made by the people who work on PHP itself, so I assumed it would be the most idiomatically sound framework for PHP applications. In other words, applications written using Zend would make sense in the context of PHP expertise.

I downloaded it, set it up on my computer, and got started. The setup was easy enough, and the configuration process seemed reasonable. Then I started going through the Quick Start guide, working through the example application. I got to the section on creating a model. When I started really looking at how Zend models work, I decided that the framework requires too much typing, and moved on to other things.

CodeIgniter

CodeIgniter is a much simpler framework created by EllisLabs. I’ve used it on two other projects, and was vaguely dissatisfied with it, but decided to give it another shot, because I really do appreciate its strengths. My main gripe in the past has been that CodeIgniter models are really DAOs and I’ve been spoiled by Hibernate and ActiveRecord. What’s particularly frustrating is that the documentation is written by someone who doesn’t understand the difference between the DAO pattern and real object-relational modeling, so it’s easy to get the wrong impression of the capabilities of the framework.

CodeIgniter is trivial to set up, and I got as far as creating a new application and implementing some test functionality. The first (minor) disappointment was the fact that CodeIgniter has no built in support for layouts. Fortunately I was able to find a simple workaround on the forums that works quite well.

Then I learned about CodeIgniter’s philosophical stance against the query string. I knew I was in trouble when I read the following in the documentation for the Input library:

Destroys the global GET array. Since CodeIgniter does not utilize GET strings, there is no reason to allow it.

Let me just say, CodeIgniter may not use the GET array, but my application certainly will. Let’s say I’m writing a report that takes parameters like sort_field and sort_order and timeframe. The most sensible way to approach the problem is to include name-value pairs in the URL. Using POST is not an option for reasons of bookmarking alone.

Eliminating the use of parameters in the query string completely is just an awful thing for a framework to do. Given that this is blindingly obvious, lots of people have asked about it on the CodeIgniter forum. There are workarounds that require modifying the core CodeIgniter code (no thanks), but the official word is not good:

It can be fairly polarizing in the forums here, and there are plenty of existing topics to read through, so I’m going to decline to say anything other than it’s the way the framework is designed. CI wants you to use URL segments and have clean, query string free URLs. I understand if that’s not an answer that satisfies you, but I do encourage you to read through the many existing topics on the subject—the workarounds are not very severe nor hard to keep up with across updates. If it’s a feature that’s very important to you and you want to use CI to build your application, you would either need to modify CI (which is one of the great things about open source frameworks) or be willing to work around it with an external solution.

I moved on.

At this point I felt a little stuck, as I thought I was down to PHP ports of Rails. I love Ruby on Rails, but Ruby and PHP are very different languages, and the thought of PHP on Rails brings to mind Samuel Johnson’s most famous quotation:

“Sir, a woman’s preaching is like a dog’s walking on his hind legs. It is not done well; but you are surprised to find it done at all.”

CakePHP

I dismissed CakePHP out of hand, based on minimal involvement in an unpleasant project that used it and lots of complaints about it that I’ve heard second hand. I thought about it for a second, but quickly decided against it.

Symfony

My next thought was to try out Symfony. I had just started digging into some really scary looking documentation when I received a recommendation for …

Kohana

Kohana is a fork of CodeIgniter that keeps all the stuff I like and gets rid of some of the dumb stuff (like the GET method problem). It was easy to set up and easy to get started with, so I’m trying to figure out exactly which parts are the good parts and use those. We’ll see how long the relationship lasts.

PHP tip of the day

I didn’t know until just now that you don’t need to include the closing ?> in PHP files that consist entirely of code. The Drupal coding standards explain why you probably want to leave it out:

Note that the final ?> should be omitted from all code files–modules, includes, etc. The closing delimiter is optional, and removing it helps prevent unwanted white space at the end of files which can cause problems elsewhere in the system.

The most common problem it prevents is the “headers already sent” error that crops up when errant line feeds are included at the end of code files.

© 2024 rc3.org

Theme by Anders NorenUp ↑