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 [email protected]: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
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