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.