Skip to content

Conversation

@alexandre-daubois
Copy link
Member

@alexandre-daubois alexandre-daubois commented Jul 7, 2025

Allows to write such code:

// export_php:function my_array_map(array $data, callable $callback): array
func my_array_map(arr *C.zval, callback *C.zval) unsafe.Pointer {
	goArr := frankenphp.GoArray(unsafe.Pointer(arr))
	result := &frankenphp.Array{}

	for i := uint32(0); i < goArr.Len(); i++ {
		key, value := goArr.At(i)

                // Magic is here!
		callbackResult := frankenphp.CallPHPCallable(unsafe.Pointer(callback), []interface{}{value})

		if key.Type == frankenphp.PHPIntKey {
			result.SetInt(key.Int, callbackResult)
		} else {
			result.SetString(key.Str, callbackResult)
		}
	}

	return frankenphp.PHPArray(result)
}
$strArray = ['a' => 'hello', 'b' => 'world', 'c' => 'php'];
var_dump(my_array_map($strArray, 'strtoupper'));

$arr = [1, 2, 3, 4, [5, 6]];
var_dump(my_array_map($arr, function($item) {
    if (is_array($item)) {
        return my_array_map($item, function($subItem) {
            return $subItem * 2;
        });
    }

    return $item * 3;
}));

/*
Output:

array(3) {
  ["a"]=>
  string(5) "HELLO"
  ["b"]=>
  string(5) "WORLD"
  ["c"]=>
  string(3) "PHP"
}
array(5) {
  [0]=>
  int(3)
  [1]=>
  int(6)
  [2]=>
  int(9)
  [3]=>
  int(12)
  [4]=>
  array(2) {
    [0]=>
    int(10)
    [1]=>
    int(12)
  }
}
*/

@withinboredom
Copy link
Member

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
Copy link
Member Author

alexandre-daubois commented Jul 25, 2025

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 alexandre-daubois marked this pull request as ready for review July 25, 2025 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants