You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -33,7 +33,7 @@ As covered in the manual implementation section below as well, you need to [get
33
33
The first step to writing a PHP extension in Go is to create a new Go module. You can use the following command for this:
34
34
35
35
```console
36
-
go mod init github.com/my-account/my-module
36
+
go mod init example.com/example
37
37
```
38
38
39
39
The second step is to [get the PHP sources](https://www.php.net/downloads.php) for the next steps. Once you have them, decompress them into the directory of your choice, not inside your Go module:
@@ -47,10 +47,14 @@ tar xf php-*
47
47
Everything is now setup to write your native function in Go. Create a new file named `stringext.go`. Our first function will take a string as an argument, the number of times to repeat it, a boolean to indicate whether to reverse the string, and return the resulting string. This should look like this:
48
48
49
49
```go
50
+
package example
51
+
52
+
// #include <Zend/zend_types.h>
53
+
import"C"
50
54
import (
51
-
"C"
52
-
"github.com/dunglas/frankenphp"
53
55
"strings"
56
+
57
+
"github.com/dunglas/frankenphp"
54
58
)
55
59
56
60
//export_php:function repeat_this(string $str, int $count, bool $reverse): string
@@ -98,6 +102,7 @@ This table summarizes what you need to know:
The generator supports declaring **opaque classes** as Go structs, which can be used to create PHP objects. You can use the `//export_php:class` directive comment to define a PHP class. For example:
193
208
194
209
```go
210
+
package example
211
+
195
212
//export_php:class User
196
213
typeUserStructstruct {
197
214
Namestring
@@ -216,6 +233,16 @@ This approach provides better encapsulation and prevents PHP code from accidenta
216
233
Since properties are not directly accessible, you **must define methods** to interact with your opaque classes. Use the `//export_php:method` directive to define behavior:
The generator supports nullable parameters using the `?` prefix in PHP signatures. When a parameter is nullable, it becomes a pointer in your Go function, allowing you to check if the value was `null` in PHP:
func(us *UserStruct) UpdateInfo(name *C.zend_string, age *int64, active *bool) {
253
290
// Check if name was provided (not null)
@@ -275,6 +312,7 @@ func (us *UserStruct) UpdateInfo(name *C.zend_string, age *int64, active *bool)
275
312
-**PHP `null` becomes Go `nil`** - when PHP passes `null`, your Go function receives a `nil` pointer
276
313
277
314
> [!WARNING]
315
+
>
278
316
> Currently, class methods have the following limitations. **Objects are not supported** as parameter types or return types. **Arrays are fully supported** for both parameters and return types. Supported types: `string`, `int`, `float`, `bool`, `array`, and `void` (for return type). **Nullable parameter types are fully supported** for all scalar types (`?string`, `?int`, `?float`, `?bool`).
279
317
280
318
After generating the extension, you will be allowed to use the class and its methods in PHP. Note that you **cannot access properties directly**:
@@ -311,6 +349,8 @@ The generator supports exporting Go constants to PHP using two directives: `//ex
311
349
Use the `//export_php:const` directive to create global PHP constants:
312
350
313
351
```go
352
+
package example
353
+
314
354
//export_php:const
315
355
constMAX_CONNECTIONS = 100
316
356
@@ -329,6 +369,8 @@ const STATUS_ERROR = iota
329
369
Use the `//export_php:classconstant ClassName` directive to create constants that belong to a specific PHP class:
330
370
331
371
```go
372
+
package example
373
+
332
374
//export_php:classconstant User
333
375
constSTATUS_ACTIVE = 1
334
376
@@ -368,10 +410,15 @@ The directive supports various value types including strings, integers, booleans
368
410
You can use constants just like you are used to in the Go code. For example, let's take the `repeat_this()` function we declared earlier and change the last argument to an integer:
369
411
370
412
```go
413
+
package example
414
+
415
+
// #include <Zend/zend_types.h>
416
+
import"C"
371
417
import (
372
-
"C"
373
-
"github.com/dunglas/frankenphp"
374
-
"strings"
418
+
"strings"
419
+
"unsafe"
420
+
421
+
"github.com/dunglas/frankenphp"
375
422
)
376
423
377
424
//export_php:const
@@ -388,37 +435,37 @@ const MODE_UPPERCASE = 2
388
435
389
436
//export_php:function repeat_this(string $str, int $count, int $mode): string
@@ -432,9 +479,13 @@ Use the `//export_php:namespace` directive at the top of your Go file to place a
432
479
433
480
```go
434
481
//export_php:namespace My\Extension
435
-
packagemain
482
+
packageexample
436
483
437
-
import"C"
484
+
import (
485
+
"unsafe"
486
+
487
+
"github.com/dunglas/frankenphp"
488
+
)
438
489
439
490
//export_php:function hello(): string
440
491
funchello() string {
@@ -537,25 +588,26 @@ We'll see how to write a simple PHP extension in Go that defines a new native fu
537
588
In your module, you need to define a new native function that will be called from PHP. To do this, create a file with the name you want, for example, `extension.go`, and add the following code:
@@ -731,7 +783,16 @@ There's only one thing left to do: implement the `go_upper` function in Go.
731
783
Our Go function will take a `*C.zend_string` as a parameter, convert it to a Go string using FrankenPHP's helper function, process it, and return the result as a new `*C.zend_string`. The helper functions handle all the memory management and conversion complexity for us.
This approach is much cleaner and safer than manual memory management. FrankenPHP's helper functions handle the conversion between PHP's `zend_string` format and Go strings automatically. The `false` parameter in `PHPString()` indicates that we want to create a new non-persistent string (freed at the end of the request).
807
+
This approach is much cleaner and safer than manual memory management.
808
+
FrankenPHP's helper functions handle the conversion between PHP's `zend_string` format and Go strings automatically.
809
+
The `false` parameter in `PHPString()` indicates that we want to create a new non-persistent string (freed at the end of the request).
747
810
748
811
> [!TIP]
812
+
>
749
813
> In this example, we don't perform any error handling, but you should always check that pointers are not `nil` and that the data is valid before using it in your Go functions.
0 commit comments