Skip to content

Commit f775671

Browse files
authored
feat: allow creating strongly typed slices and maps from PHP values with type utilities (#1933)
* feat: use generics in type functions for better type support * various improvements * better docs * update docs
1 parent 9aee496 commit f775671

4 files changed

Lines changed: 232 additions & 99 deletions

File tree

docs/extensions.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ package example
5353
import "C"
5454
import (
5555
"strings"
56+
"unsafe"
5657

5758
"github.com/dunglas/frankenphp"
5859
)
@@ -133,7 +134,10 @@ import (
133134
// export_php:function process_data_ordered(array $input): array
134135
func process_data_ordered_map(arr *C.zval) unsafe.Pointer {
135136
// Convert PHP associative array to Go while keeping the order
136-
associativeArray := frankenphp.GoAssociativeArray(unsafe.Pointer(arr))
137+
associativeArray, err := frankenphp.GoAssociativeArray[any](unsafe.Pointer(arr))
138+
if err != nil {
139+
// handle error
140+
}
137141

138142
// loop over the entries in order
139143
for _, key := range associativeArray.Order {
@@ -143,8 +147,8 @@ func process_data_ordered_map(arr *C.zval) unsafe.Pointer {
143147

144148
// return an ordered array
145149
// if 'Order' is not empty, only the key-value pairs in 'Order' will be respected
146-
return frankenphp.PHPAssociativeArray(frankenphp.AssociativeArray{
147-
Map: map[string]any{
150+
return frankenphp.PHPAssociativeArray[string](frankenphp.AssociativeArray[string]{
151+
Map: map[string]string{
148152
"key1": "value1",
149153
"key2": "value2",
150154
},
@@ -156,15 +160,18 @@ func process_data_ordered_map(arr *C.zval) unsafe.Pointer {
156160
func process_data_unordered_map(arr *C.zval) unsafe.Pointer {
157161
// Convert PHP associative array to a Go map without keeping the order
158162
// ignoring the order will be more performant
159-
goMap := frankenphp.GoMap(unsafe.Pointer(arr))
163+
goMap, err := frankenphp.GoMap[any](unsafe.Pointer(arr))
164+
if err != nil {
165+
// handle error
166+
}
160167

161168
// loop over the entries in no specific order
162169
for key, value := range goMap {
163170
// do something with key and value
164171
}
165172

166173
// return an unordered array
167-
return frankenphp.PHPMap(map[string]any{
174+
return frankenphp.PHPMap(map[string]string {
168175
"key1": "value1",
169176
"key2": "value2",
170177
})
@@ -173,15 +180,18 @@ func process_data_unordered_map(arr *C.zval) unsafe.Pointer {
173180
// export_php:function process_data_packed(array $input): array
174181
func process_data_packed(arr *C.zval) unsafe.Pointer {
175182
// Convert PHP packed array to Go
176-
goSlice := frankenphp.GoPackedArray(unsafe.Pointer(arr), false)
183+
goSlice, err := frankenphp.GoPackedArray(unsafe.Pointer(arr), false)
184+
if err != nil {
185+
// handle error
186+
}
177187

178188
// loop over the slice in order
179189
for index, value := range goSlice {
180190
// do something with index and value
181191
}
182192

183193
// return a packed array
184-
return frankenphp.PHPackedArray([]any{"value1", "value2", "value3"})
194+
return frankenphp.PHPPackedArray([]string{"value1", "value2", "value3"})
185195
}
186196
```
187197

threadworker.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package frankenphp
44
import "C"
55
import (
66
"context"
7+
"fmt"
78
"log/slog"
89
"path/filepath"
910
"time"
@@ -245,7 +246,12 @@ func go_frankenphp_finish_worker_request(threadIndex C.uintptr_t, retval *C.zval
245246
thread := phpThreads[threadIndex]
246247
fc := thread.getRequestContext()
247248
if retval != nil {
248-
fc.handlerReturn = GoValue(unsafe.Pointer(retval))
249+
r, err := GoValue[any](unsafe.Pointer(retval))
250+
if err != nil {
251+
logger.Error(fmt.Sprintf("cannot convert return value: %s", err))
252+
}
253+
254+
fc.handlerReturn = r
249255
}
250256

251257
fc.closeContext()

0 commit comments

Comments
 (0)