Is it possible to pass PHP variable to FFI C function?

Viewed 234

I want to explore PHP variables on C level with FFI. Is it possible?
I wrote code, but it doesn't work correctly.

php_ffi.cpp

#include "zend_types.h"
#include "main/php.h"

int main() {}

extern "C" void print_zval_info(zval zv) {
    printf("type: %d\n", Z_TYPE(zv));
}

test.php

<?php

$cpp_ffi = \FFI::cdef(
    "void print_zval_info(zval zv);",
    __DIR__ . "/php_ffi.so");

$a = 1;
$cpp_ffi->print_zval_info($a);

How to reproduce:

git clone git@github.com:php/php-src.git && cd php-src
./buildconf
./configure --enable-debug --with-ffi
g++ -g -fPIC -shared -I . -I Zend -I main -I TSRM php_ffi.cpp -o php_ffi.so
php test.php
1 Answers

You can't pass PHP variable to FFI C function, but you can access that variable in C code:

library.cpp

#include "main/php.h"
#include "zend_types.h"
#include "zend_string.h"

extern "C" void test_var(char *name) {

    HashTable *symbol_table = zend_array_dup(zend_rebuild_symbol_table());

    zend_string *key_name = zend_string_init(name, strlen(name), 0);
    zval *data = zend_hash_find(symbol_table, key_name);

    if(data != NULL) {
      //do something with data
    }
  
    zend_string_release(key_name);
    zend_array_destroy(symbol_table);
}

compile library.cpp to library.so

g++ -O3 -fPIC -shared -o library.so library.cpp

test.php

<?php

function test_var($myLocalVariable) {
    $libc = \FFI::cdef("void test_var(char *name);","library.so");
    $libc->test_var('myLocalVariable');
}


$var = 1;
test_var($var);

You can see the complete example in this library

Related