Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ func process_data_packed(arr *C.zval) unsafe.Pointer {
- `frankenphp.GoAssociativeArray(arr unsafe.Pointer, ordered bool) frankenphp.AssociativeArray` - Convert a PHP array to an ordered Go `AssociativeArray` (map with order)
- `frankenphp.GoMap(arr unsafe.Pointer) map[string]any` - Convert a PHP array to an unordered Go map
- `frankenphp.GoPackedArray(arr unsafe.Pointer) []any` - Convert a PHP array to a Go slice
- `frankenphp.IsPacked(zval unsafe.Pointer) bool` - Check if a PHP array is packed (indexed only) or associative (key-value pairs)

### Declaring a Native PHP Class

Expand Down
20 changes: 20 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,26 @@ func createNewArray(size uint32) *C.HashTable {
return (*C.HashTable)(unsafe.Pointer(arr))
}

// IsPacked determines if the given zval pointer represents a packed array (list).
// Returns false if the zval is nil, not an array, or not packed.
func IsPacked(zval unsafe.Pointer) bool {
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it take a HashTable instead of a zval?

Copy link
Member Author

Choose a reason for hiding this comment

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

Exported functions receive arrays as a zval. That's why I preferred to create a new function instead of just exposing htIsPacked: it's a bit more flexible and allow a quick check without having to do manual casts

Copy link
Member

Choose a reason for hiding this comment

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

See #1894

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah yes, let's wait for it to be merged before going forward with this one then 🙂

if zval == nil {
return false
}

v, err := extractZvalValue((*C.zval)(zval), C.IS_ARRAY)
if err != nil {
return false
}

ht := (*C.HashTable)(v)
if ht == nil {
return false
}

return htIsPacked(ht)
}

// htIsPacked checks if a HashTable is a list (packed) or hashmap (not packed).
func htIsPacked(ht *C.HashTable) bool {
flags := *(*C.uint32_t)(unsafe.Pointer(&ht.u[0]))
Expand Down