Skip to content

Conversation

@alexandre-daubois
Copy link
Member

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

This brings support for arrays in parameters and return types, and writing such code:

// export_php:function my_array_sum(array $numbers): int
func my_array_sum(numbers *C.zval) int64 {
	if numbers == nil {
		return 0
	}

	phpArray := frankenphp.GoArray(unsafe.Pointer(numbers))

	sum := int64(0)

	for i := uint32(0); i < phpArray.Len(); i++ {
		_, value := phpArray.At(i)
		if num, ok := value.(int64); ok {
			sum += num
		}
	}
	return sum
}

// export_php:function create_range(int $start, int $end): array
func create_range(start int64, end int64) unsafe.Pointer {
	result := &frankenphp.Array{}
	for i := start; i <= end; i++ {
		result.Append(i)
	}

	return frankenphp.PHPArray(result)
}

TODO:

  • Warn about non-scalar items being treated as null

@alexandre-daubois alexandre-daubois force-pushed the arrays-support branch 4 times, most recently from 428a194 to fe73d31 Compare July 4, 2025 15:08
@alexandre-daubois alexandre-daubois force-pushed the arrays-support branch 4 times, most recently from 39fc120 to e0379da Compare July 6, 2025 14:54
@alexandre-daubois
Copy link
Member Author

CI fixed and green 👍

Copy link
Member

@withinboredom withinboredom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exciting times! My only concern is that we're passing zvals. How does that impact GC on the PHP side? Do we need to update the ref-counts of the zval? For example, if I have the following code:

function foo() {
  // set a global in the extension, the value will be gc'd upon return
  set_my_ext_global([]);
}

foo();
var_dump(get_my_ext_global());

In this case, we won't have a memory leak (the original [] gets destroyed), and we actually get a deep copy later? Or, is there a reference still to [] hanging around?


isList := true
for i, k := range arr.keys {
if k.Type != PHPIntKey || k.Int != int64(i) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this be an issue on 32bit machines where the keys will be 32 bits?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be good, manipulating int64 on 32 bits system is just a bit slower. But we can also type it with int instead of int64, so it adapts depending on the system. Not sure which would be better, given that 32 bits system are becoming pretty rare

Copy link
Member

@withinboredom withinboredom Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually came up on php-internals recently. It is less rare than you'd think. For example, wasm implementations and emulators on ios are 32 bit.

@alexandre-daubois
Copy link
Member Author

is there a reference still to [] hanging around?

It shouldn't as the copy is stored in the Go-side (if we have a global var in the extension). To me, we don't need to update the refcount as long as we don't support references (it should be documented as well in the doc indeed). Also we use emalloc, so it should be safe as well for the GC if I get it correctly

@alexandre-daubois alexandre-daubois force-pushed the arrays-support branch 4 times, most recently from ef86b31 to bee717a Compare July 9, 2025 13:32
@alexandre-daubois
Copy link
Member Author

All comments addressed, thanks for the review!

@dunglas dunglas merged commit 8df4123 into php:main Jul 16, 2025
9 checks passed
@dunglas
Copy link
Member

dunglas commented Jul 16, 2025

Thanks!

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.

4 participants