PHP Extension(C/C++)の中でPHPのコードを実行する

PHPで処理速度を上げたい時や、メモリ使用量を減らしたい時に、「C/C++でExtensionを自作する」という最終手段があります。

Extensionは非常に強力ですが、一方でどうしようもなく開発効率が悪い。

そういう意味で、C/C++のExtensionの中でPHPを実行したいこともある(かもしれません)。

そんな時に使えるのがzend_eval_string()です。

本来であれば下のようなコードを書かなければならないところを...

PHP_FUNCTION(foobar_test)
{
    zval zv;

    // zvを [10,20,30] という配列にしたい!
    array_init(&zv);
    add_next_index_long(&zv, 10);
    add_next_index_long(&zv, 20);
    add_next_index_long(&zv, 30);

こんな風に書ける。

#include <zend_execute.h>

PHP_FUNCTION(foobar_test)
{
    zval zv;

    // 1行で [10,20,30] ができる!
    zend_eval_string("[10,20,30]", &zv, "test desukara");

関数名から分かるようにeval()しているのと同じです。

当然ですが、

  • 性能のためにC/C++にしているのに、PHPを実行したら本末転倒になる
  • 動的にPHPコードを作ると脆弱性になる可能性がある

という問題はあります。ただし、込み入った連想配列を定義するときなどに使えば楽だろうなとは思います(個人的には使ったことないですが)。

ちなみに、PHP本体(7.4)のソースコードzend_eval_stringgrepすると、下のものを含めていくつかヒットしました。

PCREのe修飾子はPHP7で廃止されたんですが、mb_ereg系ではまだ現役で使えるようです(知らなかった)。