Playing with PHP extensions: building a map

I’ve ran into PHP-CPP, a C++ library which helps you build your own PHP extensions in an easier way than writing them from scratch. And I decided to play a little bit. It has good documentation and examples.

Installing is not always out of the box depending on the environment. I like to keep things clean on my working machines so I wanted to have everything in a Docker container, but I quickly ran into an issue installing the library. Fortunately, I’ve found a solution pretty fast.

The first idea that came into my mind was a simple map. Nothing special, I’m not bringing any improvements, I just wanted to convert the following into an extension.

class PhpMap
{
    private $container = [];

    public function set(string $key, $value) {
        $this->container[$key] = $value;
    }

    public function get(string $key) {
        return $this->has($key) ? $this->container[$key] : null;
    }

    public function has(string $key) : bool {
        return array_key_exists($key, $this->container);
    }

    public function delete(string $key) {
        if ($this->has($key)) {
            unset($this->container[$key]);
        }
    }

    public function length() : int {
        return count($this->container);
    }

    public function range(callable $callback) : array {
        $items = [];
        foreach ($this->container as $key => $value) {
            if ($callback($value, $key) === true) {
                $items[$key] = $value;
            }
        }
        
        return $items;
    }
}

PHP-CPP offers some shortcuts, including base classes, methods parameters, and data types which make everything smooth. I had to implement my class, create an extension object, register the methods I want to be accessible from PHP, and add my class to the extension.

When you declare a method, instead of using C++ types, you use the ones provided by the library:

Php::Value has(Php::Parameters ¶ms) {
   ...
}

And when you register a method to PHP, you can specify the types of the parameters and whether they are required or not:

Php::Class<Map> map("Map");

map.method<&Map::set> ("set", {
    Php::ByVal("key", Php::Type::String, true),
    Php::ByVal("value", Php::Type::Null, true)
});</pre>

See full source code on GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.