php goodness

Alternative PHP mock object

Posted in Short by phpgoodness on June 7, 2011

I created a small github repo where I publish the project of the weekend, PHPTestDummy.

PHPTestDummy is a framework that creates mock objects of your PHP classes. It is capable to define actions for stubs and giving information of the stub calls to be used for assertions. Is might be an alternative mock object solution for PHPUnit.

See: php-test-dummy.org and github/tcz/PHPTestDummy

PHPTestDummy is in an “alpha” stage and therefore it can be buggy. Please report any problem you encounter in the Github issues section. Quite some improvements are planned to be implemented soon, but please, if you specificly would like to see something, open an issue as well.

Tagged with: ,

PHPTracker

Posted in Short by phpgoodness on February 25, 2011

PHPTracker It took my spare time in the last couple of days to finish the first release of a project called PHPTracker.

It is an all in one Bittorrent creator, tracker server and seed server written in PHP. It creates you the .torrent file, manages peer announcements and initially serves your file. Ideal when your website serves big files with high traffic (for example your software you developed). Good thing about it, when you have enough external seeders, it automatically stops seeding from your server saving you a significant amount of money on bandwidth.

PHPTracker is released under the BSD license and can be downloaded here:

PHPTracker

Simple examples follow.

Creating torrent file

// -----------------------------------------------------------
// This is how to create a .torrent file from a physical file.
// -----------------------------------------------------------

// Registering autoloader, essential to use the library.
require( dirname(__FILE__).'/lib/PHPTracker/Autoloader.php' );
PHPTracker_Autoloader::register();

// Creating a simple config object. You can replace this with your object
// implementing PHPTracker_Config_Interface.
$config = new PHPTracker_Config_Simple( array(
    // Persistense object implementing PHPTracker_Persistence_Interface.
    // We use MySQL here. The object is initialized with its own config.
    'persistence' => new PHPTracker_Persistence_Mysql(
        new PHPTracker_Config_Simple( array(
            'db_host'       => '192.168.1.100',
            'db_user'       => 'misc',
            'db_password'   => 'misc',
            'db_name'       => 'misc',
        ) )
    ),
    // List of public announce URLs on your server.
    'announce'  => array(
        'http://php-tracker.dev/example_announce.php',
    ),
) );

// Core class managing creating the file.
$core = new PHPTracker_Core( $config );

// Setting appropiate HTTP header and sending back the .torrrent file.
// This is VERY inefficient to do! SAVE the .torrent file on your server and
// serve the saved copy!
header( 'Content-Type: application/x-bittorrent' );
header( 'Content-Disposition: attachment; filename="test.torrent"' );

// The first parameters is a path (can be absolute) of the file,
// the second is the piece size in bytes.
echo $core->createTorrent( 'netbeans.exe', 524288 );

Preparing announce URL

// ---------------------------------------
// This is how to set up an announce URL.
// ---------------------------------------

// Registering autoloader, essential to use the library.
require( dirname(__FILE__).'/lib/PHPTracker/Autoloader.php' );
PHPTracker_Autoloader::register();

// Creating a simple config object. You can replace this with your object
// implementing PHPTracker_Config_Interface.
$config = new PHPTracker_Config_Simple( array(
    // Persistense object implementing PHPTracker_Persistence_Interface.
    // We use MySQL here. The object is initialized with its own config.
    'persistence' => new PHPTracker_Persistence_Mysql(
        new PHPTracker_Config_Simple( array(
            'db_host'       => '192.168.1.100',
            'db_user'       => 'misc',
            'db_password'   => 'misc',
            'db_name'       => 'misc',
        ) )
    ),
    // The IP address of the connecting client.
    'ip'        => $_SERVER['REMOTE_ADDR'],
    // Interval of the next announcement in seconds - sent back to the client.
    'interval'  => 60,
) );

// Core class managing the announcements.
$core = new PHPTracker_Core( $config );

// We take the parameters the client is sending and initialize a config
// object with them. Again, you can implement your own Config class to do this.
$get = new PHPTracker_Config_Simple( $_GET );

// We simply send back the results of the announce method to the client.
echo $core->announce( $get )

Starting seed server

// --------------------------------------
// This is how to start a seeding server.
// --------------------------------------

// [!] Run this file in CLI only!
// /usr/bin/php example_seeder.php

// Registering autoloader, essential to use the library.
require( dirname(__FILE__).'/lib/PHPTracker/Autoloader.php' );
PHPTracker_Autoloader::register();

// Persistense object implementing PHPTracker_Persistence_Interface.
// We use MySQL here. The object is initialized with its own config.
$persistence = new PHPTracker_Persistence_Mysql(
    new PHPTracker_Config_Simple( array(
        'db_host'       => '192.168.1.100',
        'db_user'       => 'misc',
        'db_password'   => 'misc',
        'db_name'       => 'misc',
    ) )
);

// Setting up seeder peer. This will listen to connections and serve files.
$peer = new PHPTracker_Seeder_Peer(
    new PHPTracker_Config_Simple( array(
        'persistence'           => $persistence,
        // PUBLIC address of the seeder server. This will be used fr announcements (ie. sent to the clients).
        'seeder_address'        => '192.168.1.100',
        'seeder_port'           => 6881,
        // Number telling how many processes should be forked to listen to incoming connections.
        'peer_forks'            => 10,
        // If specified, gives a number of outsider seeders to make self-seeding stop.
        // This saves you bandwidth - once your file is seeded by others, you can stop serving it.
        // Number of seeders is permanently checked, but probably 1 is too few if you want your file to be available always.
        'seeders_stop_seeding'  => 5,
    )
) );

// We set up a seeding server which starts the seeding peer, and makes regular
// announcements to the database adding itself to the peer list for all
// active torrents.
$server = new PHPTracker_Seeder_Server(
     new PHPTracker_Config_Simple( array(
        'persistence'           => $persistence,
        'peer'                  => $peer,
    )
) );

$server->start();

Do you like it?

Some PHP performance myths

Posted in Short by phpgoodness on July 23, 2010

Let’s do some benchmarking and prove (or disprove) some urban legends.

Echo vs Print

Echo claimed to be quicker, since actually it’s not a function (but a language construct), and therefore it doesn’t return a value. Print is not a real function either, but acts like a function, and always returns 1.

Also, to echo you can pass comma-separated strings and it will output hem right aways, one by one (just like your would have several different echos following each other), that is, PHP doesn’t need to concatenate them first in the memory, they can be written to the output immediately.

Average, relative 1000 10000 1000000
echo, with comma 1,00 700ms 6528ms 583318ms
echo, with concat 1,06 740ms 6425ms 670096ms
print, with concat 1,12 773ms 6841ms 700804ms

As you can see the theory is works in practice, although the difference is not that big. I used 4 separate strings with 4-8 characters. If you code (and if you still use direct output writing at all), try using echo with commas.

Increment

Incrementing (or decrementing) an integer with 1 is a quite common operation again. You can do it (at least) in 4 ways using PHP.

Average, relative 1000 10000 1000000
++$j; 1,00 281ms 2375ms 228295ms
$j++; 1,20 358ms 2759ms 265173ms
$j += 1; 1,20 342ms 2843ms 273779ms
$j = $j + 1; 1,33 368ms 3150ms 307458ms

++$j (pre-increment) is markedly quicker than the others (20%-30%). Why? All the other operations first copy the value of $j to the memory, increment it there (in that temporary register) and then assign it to $j. This is obvious for the last 2 cases, but what about $j++ (post-increment)?

The difference between the two increment operator is that the latter ($j++) first return the original value of $j, and then increments it. That is, it needs the copy of the value. If use increment operation in a void context (that is, you simply want to increment the value), use ++$j.

Instanceof

I think it is a not very well-known performance issue. Apparently PHP uses string comparison to determine is an object is an instance of a class. Though instanceof operator is pretty quick, it’s not all the same, how long is your class name.

Average, relative 1000 10000 1000000
Short classname: (1 char): 1,00 449ms 3615ms 356093ms
Long classname (26 char): 1,84 760ms 6852ms 684316ms
Very long classname (78 char): 3,74 1495ms 14234ms 1405590ms

See? Pretty amazing difference. So readability vs performance? Since instanceof is not a frequently used operation, I vote for long (but readable) class names, but if you use if often, you may consider removing some extra characters.

For the tests I used PHP 5.2.5, command line execution on Debian. On a request I can add the benchmarking scripts to the post.

Singleton (and multiton) with a different approach

Posted in Long by phpgoodness on July 21, 2010

Is this familiar to you?

class SingletonClass
{
	protected static $instance = null;

	protected function __construct()
	{
		// ...
	}

	final protected function __clone()
	{
	}

	public static function getInstance()
	{
		$classname = __CLASS__;
		if ( !self::$instance || !self::$instance instanceof $classname )
		{
			self::$instance = new self();
		}

		return self::$instance;
	}
}

Yes, the good old Singleton in the classic implementation; static getInstance, protected (maybe final) constructor (and clone magic method), and storing the only-one instance within the class. And there is, of course, the Multiton as well (what a lame name anyway), which normally has very similar implementation.

I personally don't always prefer coding Singleton like this.

Somehow this logic doesn't belong to what the class should do, the class should only take care about its job and no more. Also, imagine yourself one day waking up and deciding to change an existing class of yours to Singleton (or a Singleton class to non-singleton). It's gonna be a tough going. And third, it's against the DRYYI methodology - that is, Don't Repeat Yourself You Idiot.

So what do I do?

If you have ever worked with PHP frameworks (or mayhap developed one) you are going to be familiar to the concept of not using new keyword, instead, you use a special method to instantiate an object. In our case, there will be a class that takes care of instantiating objects based on their type.

The goal is something like this:

$singleton_1 = Object::get( 'SomethingSingleton', $param_1, $param_2 );
$singleton_2 = Object::get( 'SomethingSingleton', $param_1, $param_2 );

$normal_1 = Object::get( 'SomethingNormal', $param_1, $param_2 );
$normal_2 = Object::get( 'SomethingNormal', $param_1, $param_2 );

And that's all. We don't have to care about anything when we get the instance of an object. In the example above the two singleton variables will refer to the same instance of 'SomethingSingleton', and the two normal variables will point to two different instances accordingly.

To "mark" a class as Singleton we are going to use interfaces. The cool thing about interfaces is that they can be used as "tags" or "labels" for a class indicating one certain behaviour.

/**
 * Singleton interface used as "tag" to mark singleton classes.
 */
interface Singleton
{
}

/**
 * Multiton interface used as "tag" to mark singleton classes.
 */
interface Multiton
{
	/**
	 * GetFace in the class should return a scalar that is used to differentiate between class instances.
	 * 
	 * For example: database names for DB classes.
	 * It is called with the construct parameters of the class.
	 */
	public static function getFace();
}

So we defined our interfaces, one for Singleton, one for Multiton. More on the getFace later. Now let's see our ...

Magic class

/**
 * Basic object defining object instantiating processes.
 */
class Object
{
	/**
	 * We store the object references of singleton classes here.
	 *
	 * Class name is the key, the object pointer is the value.
	 *
	 * @var array
	 */
	static $singletons = array();

	/**
	 * We store the object references of multiton classes here.
	 *
	 * Class names are the keys, the values are sub-arrays containing different instances (values) for diffferent "faces" (keys).
	 * For example:
	 * array(
	 * 	'Database' => array(
	 *		'db_server_1' => $db_object_for_server_1,
	 *		'db_server_2' => $db_object_for_server_2,
	 *	),
	 *	'AnotherCclass' => array()
	 * );
	 *
	 * @var array
	 */
	static $multitons = array();

	/**
	 * Method to instantiate objects in general.
	 *
	 * The logic decides if the class is a singleton, multiton or normal object,
	 * and returns instance accordingly.
	 * Passing additional parameters will cause the object constructors to be
	 * called with these parameters. It only occurs, when the the method needs
	 * to create a new instance.
	 *
	 * @param string $class_name The class name to intantiate the object from.
	 * @return object The new or already existing instane of the object.
	 */
	static function get( $class_name )
	{
		// If the class is in the singleton array, we are sure that we don't need another instance.
		if ( isset( Object::$singletons[$class_name] ) )
		{
			return Object::$singletons[$class_name];
		}

		// Parameters to call constructor (in case) and multiton's getFace (in case) with.
		$construct_params = func_get_args();
		array_shift( $construct_params );

		// If the class is in the multiton array with the same "face" scalar, we don't need another instance.
		if
		(
				isset( Object::$multitons[$class_name] )
				&&
				isset( Object::$multitons[$class_name][$multiton_param_processed = call_user_func_array( array( $class_name, 'getFace' ), $construct_params )] )
		)
		{
			return Object::$multitons[$class_name][$multiton_param_processed];
		}

		// Here's the point where we have to instanceate the class anyway.
		$reflection = new ReflectionClass( $class_name );
		
		if ( null === $reflection->getConstructor() )
		{
			// If the object doesn't have constructor, we just instantiate it.
			// It might be quicker to use - new $class_name -.
			$new_instance = $reflection->newInstance();
		}
		else
		{
			// If the object does have constructor, we pass the additional parameters we got in thos method.
			$new_instance = $reflection->newInstanceArgs( $construct_params );
		}

		// If it's a singleton, we have to keep track of it.
		// If might be quicker to use - $new_instance instanceof Singleton -.
		if ( $reflection->isSubclassOf( 'Singleton' ) )
		{
			return Object::$singletons[$class_name] = $new_instance;
		}
		// If it's a multiton, we have to keep track of it with its "face".
		// If might be quicker to use - $new_instance instanceof Singleton -.
		if ( $reflection->isSubclassOf( 'Multiton' ) )
		{
			if ( !isset( $multiton_param_processed ) )
			{
				$multiton_param_processed = call_user_func_array( array( $class_name, 'getFace' ), $construct_params );
			}
			return Object::$multitons[$class_name][$multiton_param_processed] = $new_instance;
		}
		return $new_instance;
	}
}

Okay, everybody hates reading someone else's code, so...

Let's do it together

We have two object pools defined as static properties of the class. The first will serve as storage for Singleton objects, the second (guess what?) for Multitons. In both cases the array keys for the pool will be the class name. For Object::$multitons we also define a sub-hierarchy where the keys are the "faces" of the multiton objects. By "faces" I mean a scalar that identifies an object instance and makes it exclusive.

When the Object::get method executes, first it checks for the class name in the singleton pool. If it's there, it means that we already created in once, and that it's singleton, so we can just return it and it's the end of the story.

It's a bit more complicated for the multiton pool. First it looks up for the class name just like for the Singleton, but if it founds it, it needs to look for the class "face" as well in the sub-hierarchy. Here is when the getFace steps to the stage.

The implemented getFace method of our multiton class is getting called with all the parameters of the Object::get, except for the first one, which is the class name. This static method of the multiton should define the "face" of the object, that is, a scalar used to mark its different instances. We are going to see later, that the same parameter set is used to construct the object (if needed).

If the face returned by getFace is found in the multiton pool, the according object instance gets returned.

Are you still with me?

I hope so. If you reached this point in the method, it means that you have to construct the new object instance (because even if the class is singleton or multiton, it doesn't have its first instance). To do this, we are going to use the reflection abilities of PHP, which is pretty cool though not very well-known.

How does it work? We create a reflection object for our class so thus with this object we will be able to get some information about the code of the class, and do some operations on it. Like, in our case, we first ask the reflection object if the class has any constructor (yes, it works for the ancestor classes too). If so, we call the constructor with the parameters passed to Object::get (except the first, eh). If there's no constructor, we simply create a new instance of the object.

OK, now we have our object instance. All we have to do is to check if it's Singleton or Multiton (or neither), and if so, save it to the according object pool. To do this, we can use our reflection object again (though instanceof operator might be faster). Of couse, in case of multiton, we also have to calculate the "face", if we still did not.

At the end, we just return the new object. Huh. Do you like it?

Pros and cons

The clear benefit here is that the object instantiating logic got placed into a specific class and doesn't taint our classes and makes it all maintainable. If you use Object::get method every time you create an object, changing normal classes and singleton classes back and forth will be very easy. On the performance side, using reflection makes it a little bit expensive, but actually I did not do any benchmarking. I don't think this means serious overhead, and reflection is widely used in some popular frameworks.

Applause!

What else? Enhancing Object class? For example, this class could be responsible for lazy-loading. Another good idea is to extend it to a lookup class for your object instances. The number of possibilities are infinite.

At last, here is an example of using getFace for those who still don't get it.

/**
 * Database connection class implementing multiton.
 */
class DatabaseConnection implements Multiton
{
	public function __construct( $database_server, $database_user, $database_password, $database_port = 3306 )
	{
		// Do what you do.
	}
	
	public static function getFace()
	{
		// Concatenating the database host, and user.
		// This will differentiate between the instances of this class.
		return func_get_arg( 0 ) . ":" . func_get_arg( 1 );
	}
}

$connection1 = Object::get( 'DatabaseConnection', '127.0.0.1', 'mrbuzzk', 'abcdefgh' );
$connection2 = Object::get( 'DatabaseConnection', '127.0.0.1', 'mrbuzzk', 'abcdefgh', 3306 );
$connection3 = Object::get( 'DatabaseConnection', '192.168.120.1', 'mrbuzzk', 'abcdefgh', 3306 );

// Connection 1 == Connection 2.
// Connection 1 != Connection 3.
// Connection 2 != Connection 3.

Late static binding before PHP 5.3

Posted in Short by phpgoodness on July 20, 2010

If you are still lazy (or funk) to upgrade to PHP 5.3 and use the numerous cool new features, or your hands are simply tied because of those nasty backwards compatibility issues, here’s a little trick how to emulate late static binding (or why don’t we call it static dynamic binding).

Let’s start with class constants. Feel free to use this piece of code to access child class constants from the parent:


constant( get_class( $this ) . '::CONSTANT_NAME' );

For static methods:

call_user_func( array( get_class( $this ), 'method_name' ), 'param1' );

And (eeh) for variables:

eval( 'return ' . get_class( $this ) . '::$variable;' );

Finally, putting this all together in one horrible example:

class A
{
	function  __construct()
	{
		call_user_func(
			array( get_class( $this ), 'echoHello' ),
			constant( get_class( $this ) . '::SAYING_HELLO' ),
			eval( 'return ' . get_class( $this ) . '::$name;' )
		);
	}
}
class B extends A
{
	const SAYING_HELLO = 'Hi';
	static $name = 'Mr. Buzz Killington';
	static function echoHello( $saying_hello, $name )
	{
		echo "$saying_hello $name";
	}
}
$b = new B;

What's the problem here? There are 3 issues why you still have to do that damn upgrade.

  1. Ugly.
  2. Performance; this is simply slow.
  3. This is not real late static binding. In real late static binding you will execute the method that is defined in the latest derived class where the static method is defined. In our case, this class is always the currently executing, final class (the class of $this), so we don't really talk about inheritance here.To hack "real" static binding, you should iterate through the parents one by one of the class of $this in case the method (or variable or constant) is not defined.

Conclusions? If you really need late static binding, you'd better upgrade, or simply don't use static methods variables and class constants.

Follow

Get every new post delivered to your Inbox.