diff --git a/README.md b/README.md index 2b56466..cb6bdc6 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,10 @@ opcache.enable_cli=1 ffi.enable="true" ; List of headers files to preload, wildcard patterns allowed. `ffi.preload` has no effect on Windows. -; see headers directory `your-php-version` -;ffi.preload=path/to/vendor/symplely/zend-ffi/headers/ze(your-php-version)_generated.h +; See headers directory for `your-php-version`, this feature is untested, since not enabled for Windows. +;ffi.preload=path/to/vendor/symplely/zend-ffi/headers/ze(your-php-version).h +;This feature is untested. ;opcache.preload==path/to/vendor/symplely/zend-ffi/preload.php ``` diff --git a/preload.php b/preload.php index eb8769a..6645220 100644 --- a/preload.php +++ b/preload.php @@ -357,17 +357,26 @@ function is_cdata($ptr): bool } /** - * Checks whether the given object is `FFI\CData`, and has the given `field`. + * Checks whether the given _c struct_ object is `FFI\CData`, and has the given member `field`. * * @param object $ptr - * @param string $field + * @param string $field member depth, up three levels *c_field0->c_field1->c_field2* * @return boolean */ - function is_cdata_valid(object $ptr, string $field) + function is_cdata_valid(object $ptr, string $field): bool { try { - $isValid = \ffi_object($ptr)->{$field}; - return \is_null($isValid) || !\is_null($isValid); + if (\strpos($field, '->') !== false) { + $fields = \explode('->', $field); + if (\count($fields) == 3) + \ffi_object($ptr)->{$fields[0]}->{$fields[1]}->{$fields[2]}; + elseif (\count($fields) == 2) + \ffi_object($ptr)->{$fields[0]}->{$fields[1]}; + } else { + \ffi_object($ptr)->{$field}; + } + + return true; } catch (\Throwable $e) { return false; } @@ -639,7 +648,7 @@ function zend_preloader(): void if (\IS_WINDOWS) { $mmap_header = __DIR__ . '\\headers\\windows_mman.h'; if (\file_exists('vendor\\symplely\\zend-ffi')) { - $vendor_code = \str_replace('.h', '_vendor.h', $mmap_header); + $vendor_code = \str_replace('.h', '_generated.h', $mmap_header); if (!\file_exists($vendor_code)) { $file = \str_replace( 'FFI_LIB ".', diff --git a/tests/900-misc_general_c.phpt b/tests/900-misc_general_c.phpt index 190fcf5..a0b6f85 100644 --- a/tests/900-misc_general_c.phpt +++ b/tests/900-misc_general_c.phpt @@ -25,6 +25,9 @@ $cs = c_struct_type('_php_socket', 'ze', [ 'std' => ZendObject::init($ci)()[0] ]); var_dump(is_cdata_valid($cs, 'blocking')); +var_dump(is_cdata_valid($cs, 'block')); +var_dump(is_cdata_valid($cs, 'zstream->value')); +var_dump(is_cdata_valid($cs, 'zstream->value->lval')); var_dump($cs->sizeof()); var_dump($cs->alignof()); var_dump($cs->char()); @@ -57,6 +60,9 @@ object(CStruct)#%d (2) { int(1477705728) } bool(true) +bool(false) +bool(true) +bool(true) int(88) int(8) object(FFI\CData:char*)#%d (1) {