mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
chore(docs): catch-up french translation (#1978)
This commit is contained in:
committed by
GitHub
parent
4e6d67e0b4
commit
1e48fbb801
@@ -88,19 +88,19 @@ While some variable types have the same memory representation between C/PHP and
|
||||
This table summarizes what you need to know:
|
||||
|
||||
| PHP type | Go type | Direct conversion | C to Go helper | Go to C helper | Class Methods Support |
|
||||
| ------------------ | ----------------------------- | ----------------- | --------------------------------- | ---------------------------------- | --------------------- |
|
||||
| `int` | `int64` | ✅ | - | - | ✅ |
|
||||
| `?int` | `*int64` | ✅ | - | - | ✅ |
|
||||
| `float` | `float64` | ✅ | - | - | ✅ |
|
||||
| `?float` | `*float64` | ✅ | - | - | ✅ |
|
||||
| `bool` | `bool` | ✅ | - | - | ✅ |
|
||||
| `?bool` | `*bool` | ✅ | - | - | ✅ |
|
||||
| `string`/`?string` | `*C.zend_string` | ❌ | `frankenphp.GoString()` | `frankenphp.PHPString()` | ✅ |
|
||||
| `array` | `frankenphp.AssociativeArray` | ❌ | `frankenphp.GoAssociativeArray()` | `frankenphp.PHPAssociativeArray()` | ✅ |
|
||||
| `array` | `map[string]any` | ❌ | `frankenphp.GoMap()` | `frankenphp.PHPMap()` | ✅ |
|
||||
| `array` | `[]any` | ❌ | `frankenphp.GoPackedArray()` | `frankenphp.PHPPackedArray()` | ✅ |
|
||||
| `mixed` | `any` | ❌ | `GoValue()` | `PHPValue()` | ❌ |
|
||||
| `object` | `struct` | ❌ | _Not yet implemented_ | _Not yet implemented_ | ❌ |
|
||||
|--------------------|-------------------------------|-------------------|-----------------------------------|------------------------------------|-----------------------|
|
||||
| `int` | `int64` | ✅ | - | - | ✅ |
|
||||
| `?int` | `*int64` | ✅ | - | - | ✅ |
|
||||
| `float` | `float64` | ✅ | - | - | ✅ |
|
||||
| `?float` | `*float64` | ✅ | - | - | ✅ |
|
||||
| `bool` | `bool` | ✅ | - | - | ✅ |
|
||||
| `?bool` | `*bool` | ✅ | - | - | ✅ |
|
||||
| `string`/`?string` | `*C.zend_string` | ❌ | `frankenphp.GoString()` | `frankenphp.PHPString()` | ✅ |
|
||||
| `array` | `frankenphp.AssociativeArray` | ❌ | `frankenphp.GoAssociativeArray()` | `frankenphp.PHPAssociativeArray()` | ✅ |
|
||||
| `array` | `map[string]any` | ❌ | `frankenphp.GoMap()` | `frankenphp.PHPMap()` | ✅ |
|
||||
| `array` | `[]any` | ❌ | `frankenphp.GoPackedArray()` | `frankenphp.PHPPackedArray()` | ✅ |
|
||||
| `mixed` | `any` | ❌ | `GoValue()` | `PHPValue()` | ❌ |
|
||||
| `object` | `struct` | ❌ | _Not yet implemented_ | _Not yet implemented_ | ❌ |
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
|
||||
@@ -47,10 +47,15 @@ tar xf php-*
|
||||
Tout est maintenant configuré pour écrire votre fonction native en Go. Créez un nouveau fichier nommé `stringext.go`. Notre première fonction prendra une chaîne comme argument, le nombre de fois à la répéter, un booléen pour indiquer s'il faut inverser la chaîne, et retournera la chaîne résultante. Cela devrait ressembler à ceci :
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
// #include <Zend/zend_types.h>
|
||||
import "C"
|
||||
import (
|
||||
"C"
|
||||
"github.com/dunglas/frankenphp"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
//export_php:function repeat_this(string $str, int $count, bool $reverse): string
|
||||
@@ -81,18 +86,20 @@ Alors que le premier point parle de lui-même, le second peut être plus diffici
|
||||
|
||||
Bien que certains types de variables aient la même représentation mémoire entre C/PHP et Go, certains types nécessitent plus de logique pour être directement utilisés. C'est peut-être la partie la plus difficile quand il s'agit d'écrire des extensions car cela nécessite de comprendre les fonctionnements internes du moteur Zend et comment les variables sont stockées dans le moteur de PHP. Ce tableau résume ce que vous devez savoir :
|
||||
|
||||
| Type PHP | Type Go | Conversion directe | Assistant C vers Go | Assistant Go vers C | Support des Méthodes de Classe |
|
||||
| ------------------ | ------------------- | ------------------ | ----------------------- | ----------------------- | ------------------------------ |
|
||||
| `int` | `int64` | ✅ | - | - | ✅ |
|
||||
| `?int` | `*int64` | ✅ | - | - | ✅ |
|
||||
| `float` | `float64` | ✅ | - | - | ✅ |
|
||||
| `?float` | `*float64` | ✅ | - | - | ✅ |
|
||||
| `bool` | `bool` | ✅ | - | - | ✅ |
|
||||
| `?bool` | `*bool` | ✅ | - | - | ✅ |
|
||||
| `string`/`?string` | `*C.zend_string` | ❌ | frankenphp.GoString() | frankenphp.PHPString() | ✅ |
|
||||
| `array` | `*frankenphp.Array` | ❌ | frankenphp.GoArray() | frankenphp.PHPArray() | ✅ |
|
||||
| `mixed` | `any` | ❌ | `GoValue()` | `PHPValue()` | ❌ |
|
||||
| `object` | `struct` | ❌ | _Pas encore implémenté_ | _Pas encore implémenté_ | ❌ |
|
||||
| Type PHP | Type Go | Conversion directe | Assistant C vers Go | Assistant Go vers C | Support des Méthodes de Classe |
|
||||
|--------------------|-------------------------------|--------------------|-----------------------------------|------------------------------------|--------------------------------|
|
||||
| `int` | `int64` | ✅ | - | - | ✅ |
|
||||
| `?int` | `*int64` | ✅ | - | - | ✅ |
|
||||
| `float` | `float64` | ✅ | - | - | ✅ |
|
||||
| `?float` | `*float64` | ✅ | - | - | ✅ |
|
||||
| `bool` | `bool` | ✅ | - | - | ✅ |
|
||||
| `?bool` | `*bool` | ✅ | - | - | ✅ |
|
||||
| `string`/`?string` | `*C.zend_string` | ❌ | frankenphp.GoString() | frankenphp.PHPString() | ✅ |
|
||||
| `array` | `frankenphp.AssociativeArray` | ❌ | `frankenphp.GoAssociativeArray()` | `frankenphp.PHPAssociativeArray()` | ✅ |
|
||||
| `array` | `map[string]any` | ❌ | `frankenphp.GoMap()` | `frankenphp.PHPMap()` | ✅ |
|
||||
| `array` | `[]any` | ❌ | `frankenphp.GoPackedArray()` | `frankenphp.PHPPackedArray()` | ✅ |
|
||||
| `mixed` | `any` | ❌ | `GoValue()` | `PHPValue()` | ❌ |
|
||||
| `object` | `struct` | ❌ | _Pas encore implémenté_ | _Pas encore implémenté_ | ❌ |
|
||||
|
||||
> [!NOTE]
|
||||
> Ce tableau n'est pas encore exhaustif et sera complété au fur et à mesure que l'API de types FrankenPHP deviendra plus complète.
|
||||
@@ -103,61 +110,113 @@ Si vous vous référez à l'extrait de code de la section précédente, vous pou
|
||||
|
||||
#### Travailler avec les Tableaux
|
||||
|
||||
FrankenPHP fournit un support natif pour les tableaux PHP à travers le type `frankenphp.Array`. Ce type représente à la fois les tableaux indexés PHP (listes) et les tableaux associatifs (hashmaps) avec des paires clé-valeur ordonnées.
|
||||
FrankenPHP fournit un support natif pour les tableaux PHP à travers `frankenphp.AssociativeArray` ou une conversion directe vers une map ou un slice.
|
||||
|
||||
`AssociativeArray` représente une [hash map](https://fr.wikipedia.org/wiki/Table_de_hachage) composée d'un champ `Map: map[string]any` et d'un champ optionnel `Order: []string` (contrairement aux "tableaux associatifs" PHP, les maps Go ne sont pas ordonnées).
|
||||
|
||||
Si l'ordre ou l'association ne sont pas nécessaires, il est également possible de convertir directement vers un slice `[]any` ou une map non ordonnée `map[string]any`.
|
||||
|
||||
**Créer et manipuler des tableaux en Go :**
|
||||
|
||||
```go
|
||||
//export_php:function process_data(array $input): array
|
||||
func process_data(arr *C.zval) unsafe.Pointer {
|
||||
// Convertir le tableau PHP vers Go
|
||||
goArray := frankenphp.GoArray(unsafe.Pointer(arr))
|
||||
package example
|
||||
|
||||
result := &frankenphp.Array{}
|
||||
// #include <Zend/zend_types.h>
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
result.SetInt(0, "first")
|
||||
result.SetInt(1, "second")
|
||||
result.Append("third") // Assigne automatiquement la prochaine clé entière
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
result.SetString("name", "John")
|
||||
result.SetString("age", int64(30))
|
||||
|
||||
for i := uint32(0); i < goArray.Len(); i++ {
|
||||
key, value := goArray.At(i)
|
||||
if key.Type == frankenphp.PHPStringKey {
|
||||
result.SetString("processed_"+key.Str, value)
|
||||
} else {
|
||||
result.SetInt(key.Int+100, value)
|
||||
}
|
||||
// export_php:function process_data_ordered(array $input): array
|
||||
func process_data_ordered_map(arr *C.zval) unsafe.Pointer {
|
||||
// Convertir le tableau associatif PHP vers Go en conservant l'ordre
|
||||
associativeArray, err := frankenphp.GoAssociativeArray[any](unsafe.Pointer(arr))
|
||||
if err != nil {
|
||||
// gérer l'erreur
|
||||
}
|
||||
|
||||
// Reconvertir vers un tableau PHP
|
||||
return frankenphp.PHPArray(result)
|
||||
// parcourir les entrées dans l'ordre
|
||||
for _, key := range associativeArray.Order {
|
||||
value, _ = associativeArray.Map[key]
|
||||
// faire quelque chose avec key et value
|
||||
}
|
||||
|
||||
// retourner un tableau ordonné
|
||||
// si 'Order' n'est pas vide, seules les paires clé-valeur dans 'Order' seront respectées
|
||||
return frankenphp.PHPAssociativeArray[string](frankenphp.AssociativeArray[string]{
|
||||
Map: map[string]string{
|
||||
"key1": "value1",
|
||||
"key2": "value2",
|
||||
},
|
||||
Order: []string{"key1", "key2"},
|
||||
})
|
||||
}
|
||||
|
||||
// export_php:function process_data_unordered(array $input): array
|
||||
func process_data_unordered_map(arr *C.zval) unsafe.Pointer {
|
||||
// Convertir le tableau associatif PHP vers une map Go sans conserver l'ordre
|
||||
// ignorer l'ordre sera plus performant
|
||||
goMap, err := frankenphp.GoMap[any](unsafe.Pointer(arr))
|
||||
if err != nil {
|
||||
// gérer l'erreur
|
||||
}
|
||||
|
||||
// parcourir les entrées sans ordre spécifique
|
||||
for key, value := range goMap {
|
||||
// faire quelque chose avec key et value
|
||||
}
|
||||
|
||||
// retourner un tableau non ordonné
|
||||
return frankenphp.PHPMap(map[string]string {
|
||||
"key1": "value1",
|
||||
"key2": "value2",
|
||||
})
|
||||
}
|
||||
|
||||
// export_php:function process_data_packed(array $input): array
|
||||
func process_data_packed(arr *C.zval) unsafe.Pointer {
|
||||
// Convertir le tableau packed PHP vers Go
|
||||
goSlice, err := frankenphp.GoPackedArray(unsafe.Pointer(arr))
|
||||
if err != nil {
|
||||
// gérer l'erreur
|
||||
}
|
||||
|
||||
// parcourir le slice dans l'ordre
|
||||
for index, value := range goSlice {
|
||||
// faire quelque chose avec index et value
|
||||
}
|
||||
|
||||
// retourner un tableau packed
|
||||
return frankenphp.PHPPackedArray([]string{"value1", "value2", "value3"})
|
||||
}
|
||||
```
|
||||
|
||||
**Fonctionnalités clés de `frankenphp.Array` :**
|
||||
**Fonctionnalités clés de la conversion de tableaux :**
|
||||
|
||||
- **Paires clé-valeur ordonnées** - Maintient l'ordre d'insertion comme les tableaux PHP
|
||||
- **Types de clés mixtes** - Supporte les clés entières et chaînes dans le même tableau
|
||||
- **Sécurité de type** - Le type `PHPKey` assure une gestion appropriée des clés
|
||||
- **Détection automatique de liste** - Lors de la conversion vers PHP, détecte automatiquement si le tableau doit être une liste compacte ou un hashmap
|
||||
- **Les objets ne sont pas supportés** - Actuellement, seuls les types scalaires et les tableaux sont supportés. Passer un objet en tant qu'élément du tableau résultera d'une valeur `null` dans le tableau PHP.
|
||||
- **Paires clé-valeur ordonnées** - Option pour conserver l'ordre du tableau associatif
|
||||
- **Optimisé pour plusieurs cas** - Option de ne pas conserver l'ordre pour de meilleures performances ou conversion directe vers un slice
|
||||
- **Détection automatique de liste** - Lors de la conversion vers PHP, détecte automatiquement si le tableau doit être une liste packed ou un hashmap
|
||||
- **Tableaux imbriqués** - Les tableaux peuvent être imbriqués et convertiront automatiquement tous les types supportés (`int64`, `float64`, `string`, `bool`, `nil`, `AssociativeArray`, `map[string]any`, `[]any`)
|
||||
- **Les objets ne sont pas supportés** - Actuellement, seuls les types scalaires et les tableaux peuvent être utilisés comme valeurs. Fournir un objet résultera en une valeur `null` dans le tableau PHP.
|
||||
|
||||
**Méthodes disponibles :**
|
||||
##### Méthodes disponibles : Packed et Associatif
|
||||
|
||||
- `SetInt(key int64, value any)` - Définir une valeur avec une clé entière
|
||||
- `SetString(key string, value any)` - Définir une valeur avec une clé chaîne
|
||||
- `Append(value any)` - Ajouter une valeur avec la prochaine clé entière disponible
|
||||
- `Len() uint32` - Obtenir le nombre d'éléments
|
||||
- `At(index uint32) (PHPKey, any)` - Obtenir la paire clé-valeur à l'index
|
||||
- `frankenphp.PHPArray(arr *frankenphp.Array) unsafe.Pointer` - Convertir vers un tableau PHP
|
||||
- `frankenphp.PHPAssociativeArray(arr frankenphp.AssociativeArray) unsafe.Pointer` - Convertir vers un tableau PHP ordonné avec des paires clé-valeur
|
||||
- `frankenphp.PHPMap(arr map[string]any) unsafe.Pointer` - Convertir une map vers un tableau PHP non ordonné avec des paires clé-valeur
|
||||
- `frankenphp.PHPPackedArray(slice []any) unsafe.Pointer` - Convertir un slice vers un tableau PHP packed avec uniquement des valeurs indexées
|
||||
- `frankenphp.GoAssociativeArray(arr unsafe.Pointer, ordered bool) frankenphp.AssociativeArray` - Convertir un tableau PHP vers un `AssociativeArray` Go ordonné (map avec ordre)
|
||||
- `frankenphp.GoMap(arr unsafe.Pointer) map[string]any` - Convertir un tableau PHP vers une map Go non ordonnée
|
||||
- `frankenphp.GoPackedArray(arr unsafe.Pointer) []any` - Convertir un tableau PHP vers un slice Go
|
||||
|
||||
### Déclarer une Classe PHP Native
|
||||
|
||||
Le générateur prend en charge la déclaration de **classes opaques** comme structures Go, qui peuvent être utilisées pour créer des objets PHP. Vous pouvez utiliser la directive `//export_php:class` pour définir une classe PHP. Par exemple :
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
//export_php:class User
|
||||
type UserStruct struct {
|
||||
Name string
|
||||
@@ -182,6 +241,16 @@ Cette approche fournit une meilleure encapsulation et empêche le code PHP de co
|
||||
Puisque les propriétés ne sont pas directement accessibles, vous **devez définir des méthodes** pour interagir avec vos classes opaques. Utilisez la directive `//export_php:method` pour définir cela :
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
// #include <Zend/zend_types.h>
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
//export_php:class User
|
||||
type UserStruct struct {
|
||||
Name string
|
||||
@@ -214,19 +283,29 @@ func (us *UserStruct) SetNamePrefix(prefix *C.zend_string) {
|
||||
Le générateur prend en charge les paramètres nullables en utilisant le préfixe `?` dans les signatures PHP. Quand un paramètre est nullable, il devient un pointeur dans votre fonction Go, vous permettant de vérifier si la valeur était `null` en PHP :
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
// #include <Zend/zend_types.h>
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
//export_php:method User::updateInfo(?string $name, ?int $age, ?bool $active): void
|
||||
func (us *UserStruct) UpdateInfo(name *C.zend_string, age *int64, active *bool) {
|
||||
// $name est null?
|
||||
// Vérifier si name a été fourni (pas null)
|
||||
if name != nil {
|
||||
us.Name = frankenphp.GoString(unsafe.Pointer(name))
|
||||
}
|
||||
|
||||
// $age est null?
|
||||
// Vérifier si age a été fourni (pas null)
|
||||
if age != nil {
|
||||
us.Age = int(*age)
|
||||
}
|
||||
|
||||
// $active est null?
|
||||
// Vérifier si active a été fourni (pas null)
|
||||
if active != nil {
|
||||
us.Active = *active
|
||||
}
|
||||
@@ -277,6 +356,8 @@ Le générateur prend en charge l'exportation de constantes Go vers PHP en utili
|
||||
Utilisez la directive `//export_php:const` pour créer des constantes PHP globales :
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
//export_php:const
|
||||
const MAX_CONNECTIONS = 100
|
||||
|
||||
@@ -295,6 +376,8 @@ const STATUS_ERROR = iota
|
||||
Utilisez la directive `//export_php:classconstant ClassName` pour créer des constantes qui appartiennent à une classe PHP spécifique :
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
//export_php:classconstant User
|
||||
const STATUS_ACTIVE = 1
|
||||
|
||||
@@ -334,10 +417,15 @@ La directive prend en charge divers types de valeurs incluant les chaînes, enti
|
||||
Vous pouvez utiliser les constantes comme vous êtes habitué dans le code Go. Par exemple, prenons la fonction `repeat_this()` que nous avons déclarée plus tôt et changeons le dernier argument en entier :
|
||||
|
||||
```go
|
||||
package example
|
||||
|
||||
// #include <Zend/zend_types.h>
|
||||
import "C"
|
||||
import (
|
||||
"C"
|
||||
"github.com/dunglas/frankenphp"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
//export_php:const
|
||||
@@ -398,9 +486,13 @@ Utilisez la directive `//export_php:namespace` en haut de votre fichier Go pour
|
||||
|
||||
```go
|
||||
//export_php:namespace My\Extension
|
||||
package main
|
||||
package example
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
//export_php:function hello(): string
|
||||
func hello() string {
|
||||
@@ -500,16 +592,17 @@ Nous allons voir comment écrire une extension PHP simple en Go qui définit une
|
||||
|
||||
#### Définir la Fonction Go
|
||||
|
||||
Dans votre module Go vide, vous devez définir une nouvelle fonction native qui sera appelée depuis PHP. Pour ce faire, créez un fichier avec le nom que vous voulez, par exemple, `extension.go`, et ajoutez le code suivant :
|
||||
Dans votre module, vous devez définir une nouvelle fonction native qui sera appelée depuis PHP. Pour ce faire, créez un fichier avec le nom que vous voulez, par exemple, `extension.go`, et ajoutez le code suivant :
|
||||
|
||||
```go
|
||||
package ext_go
|
||||
package example
|
||||
|
||||
//#include "extension.h"
|
||||
// #include "extension.h"
|
||||
import "C"
|
||||
import (
|
||||
"log/slog"
|
||||
"unsafe"
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
@@ -520,7 +613,7 @@ func init() {
|
||||
//export go_print_something
|
||||
func go_print_something() {
|
||||
go func() {
|
||||
caddy.Log().Info("Hello from a goroutine!")
|
||||
slog.Info("Hello from a goroutine!")
|
||||
}()
|
||||
}
|
||||
```
|
||||
@@ -697,7 +790,16 @@ Il ne reste qu'une chose à faire : implémenter la fonction `go_upper` en Go.
|
||||
Notre fonction Go prendra un `*C.zend_string` comme paramètre, le convertira en chaîne Go en utilisant la fonction d'aide de FrankenPHP, le traitera, et retournera le résultat comme un nouveau `*C.zend_string`. Les fonctions d'aide gèrent toute la complexité de gestion de mémoire et de conversion pour nous.
|
||||
|
||||
```go
|
||||
import "strings"
|
||||
package example
|
||||
|
||||
// #include <Zend/zend_types.h>
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
"strings"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
)
|
||||
|
||||
//export go_upper
|
||||
func go_upper(s *C.zend_string) *C.zend_string {
|
||||
|
||||
Reference in New Issue
Block a user