Skip to content

Instantly share code, notes, and snippets.

@masakielastic
Last active May 3, 2024 23:11
Show Gist options
  • Save masakielastic/cc1a60f407af1016d5932486fb11d588 to your computer and use it in GitHub Desktop.
Save masakielastic/cc1a60f407af1016d5932486fb11d588 to your computer and use it in GitHub Desktop.
PHP FFI example
<?php
$x = FFI::new('int');
$x->cdata = 5;
var_dump(
5 === $x->cdata
);
<?php
$a = FFI::new('long[10]');
// $a = FFI::new(FFI::type('long[10]'));
// $a = FFI::new(FFI::arrayType(FFI::type('long'), [10]));
$size = count($a);
for ($i = 0; $i < $size; ++$i) {
$a[$i] = $i + 1;
}
$sum = 0;
foreach ($a as $v) {
$sum += $v;
}
var_dump(55 === $sum);
<?php
$str = '🐶🐱🐘';
$size = strlen($str);
$p = FFI::addr(FFI::new('uint8_t['.$size.']'));
// $p = FFI::addr(
// FFI::new(FFI::arrayType(FFI::type('uint8_t'), [$size]))
// );
FFI::memcpy($p, $str, $size);
var_dump(
'F09F90B6' === strtoupper(bin2hex('🐶')),
0xF0 === ord($str[0]),
0xF0 === $p[0][0],
$str === FFI::string($p[0], $size)
);
FFI::free($p);
<?php
$p = FFI::new('struct {int x,y;}');
$p->x = 1;
$p->y = 2;
var_dump(
1 === $p->x
);
<?php
// https://stackoverflow.com/a/62693231/531320
$name = 'John';
$size = strlen($name);
$struct = FFI::new('struct { uint8_t *name }');
$struct->name = FFI::new('uint8_t['.$size.']', 0);
FFI::memcpy($struct->name, $name, $size);
$ret = FFI::string($struct->name, $size);
FFI::free($struct->name);
var_dump(
NULL === $struct->name,
$name === $ret
);
<?php
$ffi = FFI::cdef('
struct header {
uint8_t *name;
uint8_t * value;
};
');
// https://nghttp2.org/documentation/tutorial-hpack.html#deflate-c
$headers = [
[':scheme', 'https'],
[':authority', 'example.org'],
[':path', '/'],
['user-agent', 'libnghttp2'],
['accept-encoding', 'gzip, deflate']
];
$size = count($headers);
$nva = $ffi->new('struct header['.$size.']');
$name = $headers[0][0];
$namelen = strlen($name);
$value = $headers[0][1];
$valuelen = strlen($value);
$nva[0]->name = FFI::new('uint8_t['.$namelen.']', 0);
FFI::memcpy($nva[0]->name, $name, $namelen);
$nva[0]->value = FFI::new('uint8_t['.$valuelen.']', 0);
FFI::memcpy($nva[0]->value, $value, $valuelen);
var_dump(
$name === FFI::string($nva[0]->name, $namelen),
$value === FFI::string($nva[0]->value, $valuelen),
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment