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.