feat(extgen): add support for callable in parameters by alexandre-daubois · Pull Request #1731 · php/frankenphp

Conversation

@alexandre-daubois

Allows to write such code:

// export_php:function my_array_map(array $data, callable $callback): array
func my_array_map(arr *C.zend_array, callback *C.zval) unsafe.Pointer {
	goSlice, err := frankenphp.GoPackedArray[any](unsafe.Pointer(arr))
	if err != nil {
		panic(err)
	}

	result := make([]any, len(goSlice))

	for index, value := range goSlice {
	  result[index] = frankenphp.CallPHPCallable(unsafe.Pointer(callback), []interface{}{value})
	}

	return frankenphp.PHPPackedArray(result)
}
use function Go\Extension\my_array_map;

$a = [1, 2, 3, 4, 5];

$b = my_array_map($a, function ($item) {
    return $item * 2;
});

var_dump($b);

/*
Output:

array(5) { [0]=> int(2) [1]=> int(4) [2]=> int(6) [3]=> int(8) [4]=> int(10) }
*/

@withinboredom

IIRC, callables are not callable from arbitrary threads (I've tried this!). Meaning if you hold a callable reference and try to call it from another php thread, it will crash. This probably just needs to be documented for authors.

Objects are the same IIRC.

HOWEVER, opcache will copy all these pointers into a shared arena during compilation, so if you have opcache turned on, it might work.

@alexandre-daubois

Meaning if you hold a callable reference and try to call it from another php thread, it will crash.

This is very unlikely I guess, but it doesn't hurt to write it in the doc indeed! Let's say that the behavior is undefined and could be unexpected

@alexandre-daubois

@php/frankenphp-collaborators this one's ready for review as well 🙂 It would be better to wait for #1894 to be merged before this one however