Hazelcast PHP Client Part I

Wolfram Hüsken recently published a blog post entitled, “Hazelcast PHP Client Part I”. In the post, Wolfram begins the adventure of building a PHP Client for Hazelcast. Be sure to follow along—the ride promises to be interesting and informative.


PHP and datatypes is like building a watch with a sledgehammer

While the cool kids talk about double precision 64-bit floating point or 32-bit unsigned integers, PHP’s only word is “numberish”…

$x = "234g";
echo ++$x . PHP_EOL;
echo $x += 5 . PHP_EOL;

234h? Seriously? So this implementation will be quite a challenge.

Enough complaining, let’s try something cool

I have to use pack() to create a binary string with all the different datatypes. I started implementing a message class, which holds the variables to build the header, the child classes, e.g. Authentication should only store the values needed for authentication.

As I’m really lazy, I want to automate the string building as far as possible. So I will have a Serializer class, which can build the string for every <? extends Message> by itself.

By using an annotation and reflection, I can query the docblocks of the private properties of the class.

That’s how my class looks like:

class AuthenticationRequest extends Message
{
    /**
     * @var string
     * @type string
     */
    private $username;
    
    /**
     * @var string
     * @type string
     */
    private $password;
    
    /**
     * @var string
     * @type string
     */
    private $uuid;
    
    /**
     * @var string
     * @type string
     */
    private $ownerUuid;
    
    /**
     * @var bool
     * @type boolean
     */
    private $isOwnerConnection;
    
    /**
     * @var string
     * @type string
     */
    private $clientType;
    
    /**
     * @var int
     * @type uint8
     */
    private $serializationVersion;
}
    

And this script will extract the datatypes:

$refl = new ReflectionClass('HazelcastMessageGenericAuthenticationRequest');
$props = $refl->getProperties(ReflectionProperty::IS_PRIVATE);
    
$map = [];
    
/** @var ReflectionProperty $prop */
foreach ($props as $prop) {
    $docBlock = $prop->getDocComment();
    $matches = [];
    
    preg_match('/@types+(w+)/m', $docBlock, $matches);
    if (!empty($matches[1])) {
        $map[$prop->getName()] = $matches[1];
    }
}
    
print_r($map);

Here the result:

Array
(
    [username] => string
    [password] => string
    [uuid] => string
    [ownerUuid] => string
    [isOwnerConnection] => boolean
    [clientType] => string
    [serializationVersion] => uint8
)

Usually these values don’t change, so they should be cached. A Memcached / Redis / File / Whatever adapter can be configured in the client config.

I hope to publish some working code as soon as possible, maybe I find some fellow devs who want to join me or report bugs…