Archive for the ‘Uncategorized’ Category

Singletons: What can they teach us about PHP?

Wednesday, March 10th, 2010

Why would I be showing you how implement singletons in PHP? Don’t I know that the singleton pattern suffers from obvious shortcomings? Of course I do, but I have an ulterior motive. Singletons are a simple way to show off some of the features of PHP you probably don’t get to see and use too often. Now we’ve got that covered let’s see some code. If you haven’t seen a Singleton before the premise is simple: there should only ever be one instance of our class.

<?php
class Greeter {
	protected $count;
 
	private function __construct() {
		$this->count = 1;
	}
 
	public function hello() {
		return 'Hi ' . $this->count++;
	}
 
	public static function getInstance() {
		static $instance = null;
		if ($instance === null) {
			$class = get_called_class();
			$instance = new $class();
		}
		return $instance;
	}
}
 
class FrenchGreeter extends Greeter {
	public function hello() {
		return 'Bonjour ' . $this->count++;
	}
}
 
echo Greeter::getInstance()->hello(); //Outputs 'Hi 1'
echo Greeter::getInstance()->hello(); //Outputs 'Hi 2'
echo FrenchGreeter::getInstance()->hello(); //Outputs 'Bonjour 1'
?>

Now, there are a few fun snippets in this piece of code. Let’s start at the top:

Private constructors

private function __construct();

A private constructor? Yep. That means that only the Greeter class can construct a new instance of itself. You can try it if you’d like:

$bob = new Greeter();
Fatal error: Call to private Greeter::__construct() from invalid context in C:\Users\Josh\Examples\singletons.php on line 1

Told you so. So this prevents anyone from sneakily constructing a new instance of the class when we’re not looking. On to the next snippet.

Static variables

public static function getInstance() {
	static $instance = null;

Defining statically scopped variables within functions is a feature borrowed from C. All static variables, whether defined in a method or in the class definition, are bound to the function and will persist across calls. The initial assignment (setting the variable to null) is only executed once – when the variable is declared. You can only assign scalar values on a static variable declaraion so the null assignment and check are necessary to if we are to assign an object or array to the variable.

You can use static variables in instance methods and plain old functions too. If you do use them in an instance method then remember that the variable is bound to the class and not the instance. Take a look at the following code:

<?php
class Counter {
	function count() {
		static $count = 1;
		return $count++;
	}
}
 
class SubCounter extends Counter { 
}
 
$a = new Counter();
$b = new Counter();
$c = new SubCounter();
echo $a->count(); //Outputs 1
echo $b->count(); //Outputs 2
echo $c->count(); //Outputs 1

Even though $a and $b are two seperate instances the static $count variable is scoped to the method, which is in turn scoped to the class, so is shared between instances. When we call the method on $c our static variable is bound to SubCounter so we get the value of 1.

Fetching the current class name

$class = get_called_class();

The get_called_class method is a long overdue addition to PHP and was added in the 5.3 release with the introduction of late static binding. The function returns the class which the current method was invoked on. The older get_class (when called with no arguments) and __CLASS__ magic constant always return the name of the class where the current method was defined (compile time binding). Let’s take a look.

<?php
class A {
	public function who() {
		echo __CLASS__;
		echo get_class();
		echo get_class($this);
		echo get_called_class();
	}
 
	public static function whoStatic() {
		echo __CLASS__;
		echo get_class();
		echo get_called_class();
	}
}
 
class B extends A {
}
 
$a = new A(); 	
$b = new B(); 	
$a->who();          //Outputs AAAA
$b->who();          //Outputs AABB
A::whoStatic();    //AAA
B::whoStatic();    //Outputs AAB

The get_class() function is a kind-of dual purpose function. If an object is passed to the function then it returns the name of that object’s class. Otherwise it acts like __CLASS__.

Instance methods always give us an implicit $this variable, which we can easily pass to get_class(). However, static methods have no such luxury. Before the introduction of late static binding there was absolutely no way to determine which class a static method was called on.

Variable variable functions

$instance = new $class();

This is one of PHP’s niftier features. Any variable lookup, function call or class instantiation can be performed on a string value. PHP calls these Variable variables and Variable functions. Let’s check out some examples.

<?php
$var = 'city';
$city = 'London';
echo $$var;	//Outputs 'London'
 
$a = 'foo';
$b = 'bar';
$foobar = 'Found me';
echo ${$a . $b}; //Outputs 'Found me'
 
$a = 'b';
$b = 'c';
$c = 'd';
$d = 'The end';
echo $$$$a; //Outputs 'The end';
 
function greeting() { echo 'Hi'; }
$func = 'greeting';
$func(); //Outputs 'Hi'

This allows for some neat meta-programming. Though care should be taken not to abuse the functionality.

So there you have it, four advanced PHP examples from one design pattern (that you should never, ever use).

Getting started with Python and Django in 23 frustrating steps.

Saturday, February 27th, 2010

Should I or shouldn’t I? Should I ditch my well-worn PHP and the frameworks I know so well to go with this new-fangled (silent-d)Jango thingy I hear the cool kids talking about? It’s a big decision, as this project is going to be the big one (you know, the one that will change the world and all that).

I’ve worked with PHP for over six years. It has it’s warts (and how) but it’s very much a known quantity at this point. On the other hand, when I have used Python it’s been a much more pleasant experience. The fact that this is a personal project makes the decision easier: let’s ditch old mate LAMPhp go with LAMPy. It’s almost dinner time and the latter sounds like it’d go well with an ale anyway. So, starting with a brand new dev box, where do I begin? (more…)

Cleaning up antiquated subversion working folders

Saturday, February 27th, 2010

Today I stumbled across an unused working folder in a dark and dusty corner of one of our development servers. The directory had a couple of dozen un-checked in changes. Some were from barely a month ago while others dated back years. Not wanting to discard any important modifirations I cobbled together a bash command to show me when each file was last modified (the file’s mtime). (more…)

Simple Atom / RSS Reader for PHP

Monday, February 8th, 2010

I was recently looking for a simple RSS reader for PHP. There are a few out there, like Magpie RSS. These seem like adequate projects, but much too high level for the scripts I was throwing together. I need to read a couple of different feed formats: namely Wordpress’ RSS feed and Flickr’s Atom feeds. I decided to put together a single-class implementation which didn’t do anything more than the bare minimum.

(more…)

Twitter is CRUD

Monday, June 2nd, 2008

Any technical person is interested in solving big challenges. How to scale well (and cheaply) is one of the really big ones; and something that no one really seems to get right. I’ve read some interesting posts discussing Twitter’s problems lately (I’m a little slow to jump on this bandwagon, but like that’s going to stop me). I haven’t been a Twitter-er up until now, but it’s hard to miss talk of them in the blogosphere.

(more…)