Archive for December, 2008

PHP !== Java

Saturday, December 20th, 2008

(This post originally appeared as part of the 2008 PHP Advent calendar)

Java has its place. Maybe it has many places. I’m OK with it being on your phone, in your refrigerator, and on my bank’s web site. I’m even OK with it making another play to be in browser applets. However, I’d really prefer if you kept it out of my PHP. I am seeing more and more PHP written as though it was Java with dollar signs. I think this is misguided.

PHP has its own pragmatic beauty. It does not try to check off enterprise buzzwords or be all things to all people. It does not try to be pure, driven down an organized roadmap, or marketed by a single owner. But it does get stuff done. Written well, it can be brief without being terse, and tidy without being restrictive. In its normal form, it will just work without significant planning and without consuming significant resources.

Using a spoken or computer language effectively is not just a matter of learning your language’s syntax and vocabulary. It is also about learning the quirks and idioms unique to that language, and using it in normal ways so that others don’t have to work to hard to understand you.

Translating the French Il pleut des cordes literally into English as It is raining ropes is nonsense. Literally translating the equivalent English Idiom It is raining cats and dogs into most other languages probably also results in nonsense. Potentially syntactically correct nonsense, potentially decipherable nonsense, but nothing that will flow naturally in conversation with a native speaker.

Translating Java literally into PHP gets similar results.

Here is a Java implementation of the singleton pattern:

public class Singleton
{
  private static Singleton myObject;

  private Singleton()
  {
     // Providing a constructor to eliminate default public one.
  }

  public static Singleton getInstance()
  {
    if (myObject == null) {
    myObject = new MyObject();
  }

    return myObject;
  }

  public Object clone() throws CloneNotSupportedException
  {
    throw new CloneNotSupportedException();
  }
}

In case you are not familiar with it, the singleton pattern is a general solution to many situations where you want only one instance of a particular class. Examples might include a database connection, a logger, or many user interface components.

Scatter a few dollar signs and make a few minor changes, and you get a valid PHP implementation:

class Singleton
{
  private static $myObject;

  private function Singleton()
  {
    // Providing a constructor to eliminate default public one.
  }

  public static function getInstance()
  {
    if (! isset(Singleton::$myObject) )
    {
      Singleton::$myObject = new MyObject();
    }

    return Singleton::$myObject;
  }

  private function __clone()
  {
  }
}

A native PHP speaker is much more likely to implement the same pattern as follows:

global $myObject;

if (!isset($myObject)) {
  $myObject = new MyObject();
}

Unfortunately, choosing this example might divert attention from the point I am trying to make. Global variables elicit a knee-jerk reaction in many people for a number of reasons, many of them good. In reality, more elaborate implementations of the singleton pattern deserve most of the same criticisms. Singletons are the object-oriented implementation of global variables.

PHP has always taken well-understood things from other languages. Why create new function names if people already know the names of the underlying C functions? Why not copy Java’s object system that many people already grasp? Why not offer Perl inventions that people find useful? But, the broth that this mix of ingredients creates has a unique flavor. It is not C, nor Java, nor Perl, and trying to program as if it is will probably leave you both missing the appeal of PHP and frustrated at the differences.

Like putting a hippo in a tutu, or a ballerina in a swamp, trying to force a language to be something it is not looks silly, works poorly, and gets leeches in your slippers.

OK, maybe I lied about the leeches.