REMARQUE:Ce site est obsolète. Le site sera désactivé après le 31 janvier 2023 et le trafic redirigera vers le nouveau site à l'adresse https://protobuf.dev. En attendant, les mises à jour ne seront effectuées que sur protobuf.dev.

Code généré par PHP

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Cette page décrit le code PHP que le compilateur de tampon de protocole génère pour une définition de protocole donnée. Lisez le guide du langage proto3 avant de lire ce document. Notez que le compilateur de tampon de protocole n'est actuellement compatible qu'avec la génération de code proto3 pour PHP.

Appel du compilateur

Le compilateur de tampon de protocole génère une sortie PHP lorsqu'elle est appelée avec l'option de ligne de commande --php_out=. Le paramètre de l'option --php_out= correspond au répertoire dans lequel vous souhaitez que le compilateur écrive votre sortie PHP. Afin de respecter le format PSR-4, le compilateur crée un sous-répertoire correspondant au package défini dans le fichier proto. De plus, pour chaque message de l'entrée du fichier proto, le compilateur crée un fichier distinct dans le sous-répertoire du package. Les noms des fichiers de sortie des messages sont composés de trois parties:

  • Répertoire de base: le chemin d'accès proto (spécifié avec l'option de ligne de commande --proto_path= ou -I) est remplacé par le chemin de sortie (spécifié avec l'option --php_out=).
  • Le sous-répertoire . du nom du package est remplacé par le séparateur de répertoire du système d'exploitation. Chaque nom de package est en majuscules.
  • Fichier: le nom du message est ajouté par .php.

Par exemple, supposons que vous appelez le compilateur comme suit :

protoc --proto_path=src --php_out=build/gen src/example.proto
src/example.proto est défini comme suit :
package foo.bar;
message MyMessage {}

Le compilateur lit les fichiers src/foo.proto et génère le fichier de sortie : build/gen/Foo/Bar/MyMessage.php. Le compilateur crée automatiquement le répertoire build/gen/Foo/Bar si nécessaire, mais il ne crée pas build ni build/gen. Ils doivent déjà exister.

Colis

Le nom de package défini dans le fichier .proto permet de générer une structure de modules pour les classes PHP générées. Exemples de fichiers :

package foo.bar;

message MyMessage {}

Le compilateur de protocole génère une classe de sortie nommée Foo\Bar\MyMessage.

Messages

Voici une déclaration de message simple :

message Foo {}

Le compilateur de tampon de protocole génère une classe PHP appelée Foo. Cette classe hérite d'une classe de base commune, Google\Protobuf\Internal\Message, qui fournit des méthodes d'encodage et de décodage des types de messages, comme illustré dans l'exemple suivant:

$from = new Foo();
$from->setInt32(1);
$from->setString('a');
$from->getRepeatedInt32()[] = 1;
$from->getMapInt32Int32()[1] = 1;
$data = $from->serializeToString();
try {
  $to->mergeFromString($data);
} catch (Exception $e) {
  // Handle parsing error from invalid data.
  ...
}

Vous ne devez pas créer vos propres sous-classes Foo. Les classes générées ne sont pas conçues pour le sous-classement et peuvent entraîner des problèmes de "classe fragile".

Les messages imbriqués génèrent une classe PHP portant le même nom, précédée du message qui les contient et séparée par un trait de soulignement, car PHP n'accepte pas les classes imbriquées. Ainsi, si vous disposez de ce qui suit dans votre fichier .proto :

message TestMessage {
  optional int32 a = 1;
  message NestedMessage {...}
}
Le compilateur génère les classes suivantes :
class TestMessage {
  public a;
}

// PHP doesn’t support nested classes.
class TestMessage_NestedMessage {...}
Si le nom de la classe de message est réservé (par exemple, Empty), le préfixe PB est ajouté au nom de la classe :
class PBEmpty {...}
Nous avons également fourni l'option au niveau du fichier php_class_prefix : Si cette valeur est spécifiée, elle est ajoutée au début de toutes les classes de message générées.

Champs

Pour chaque champ d'un type de message, il existe des méthodes d'accesseur pour définir et obtenir le champ. Ainsi, pour un champ x, vous pouvez écrire :

$m = new MyMessage();
$m->setX(1);
$val = $m->getX();

$a = 1;
$m->setX($a);

Chaque fois que vous définissez un champ, la valeur est comparée au type déclaré de ce champ. Si le type de la valeur est incorrect (ou hors plage), une exception est générée. Par défaut, les conversions de type (par exemple, lors de l'attribution d'une valeur à un champ ou de l'ajout d'un élément à un champ répété) sont autorisées vers et depuis les chaînes entières, flottantes et numériques. Les conversions non autorisées incluent toutes les conversions vers/depuis des tableaux ou des objets. Les conversions de type float à entier ne sont pas définies.

Vous pouvez voir le type de PHP correspondant à chaque tampon de protocole scalaire dans le tableau des types de valeurs scalaires.

Champs de message singuliers

Par défaut, un champ contenant un type de message est nul et n'est pas créé automatiquement lorsque l'utilisateur accède au champ. Vous devez donc créer explicitement des sous-messages, comme suit :

$m = new MyMessage();
$m->setZ(new SubMessage());
$m->getZ()->setFoo(42);

$m2 = new MyMessage();
$m2->getZ()->setFoo(42);  // FAILS with an exception

Vous pouvez attribuer n'importe quelle instance à un champ de message, même si elle est également stockée ailleurs (par exemple, en tant que valeur de champ dans un autre message).

Champs répétés

Le compilateur de tampon de protocole génère un RepeatedField spécial pour chaque champ répété. Ainsi, avec le champ suivant :

repeated int32 foo = 1;
Le code généré vous permet de le faire :
$m->getFoo()[] =1;
$m->setFoo($array);

Champs de carte

Le compilateur de tampon de protocole génère un MapField pour chaque champ de carte. Ainsi, avec ce champ :

map<int32, int32> weight = 1;

Vous pouvez effectuer les opérations suivantes avec le code généré :

$m->getWeight()[1] = 1;

Énumérations

PHP n'a pas d'énumérations natives. Le compilateur de tampon de protocole génère donc une classe PHP pour chaque type d'énumération dans votre fichier .proto, comme pour les messages, avec des constantes définies pour chaque valeur. Ainsi, avec cette énumération :
enum TestEnum {
  Default = 0;
  A = 1;
}
Le compilateur génère la classe suivante :
class TestEnum {
  const DEFAULT = 0;
  const A = 1;
}
Comme pour les messages, une énumération imbriquée renvoie une classe PHP du même nom préfixée par le ou les messages qu'elle contient, séparés par des traits de soulignement, car PHP n'accepte pas les classes imbriquées.
class TestMessage_NestedEnum {...}
Si une classe d'énumération ou un nom de valeur est réservé (Empty, par exemple), le préfixe PB est ajouté au nom de la classe ou de la valeur :
class PBEmpty {
  const PBECHO = 0;
}
Nous avons également fourni l'option au niveau du fichier php_class_prefix. Si cette valeur est spécifiée, elle est ajoutée au début de toutes les classes d'énumération générées.

Un

Pour l'un, le compilateur de tampon de protocole génère le même code que pour les champs singuliers standards, mais ajoute également une méthode d'accesseur spéciale qui vous permet de savoir lequel de ces champs est défini (le cas échéant). Voici donc ce message :

message TestMessage {
  oneof test_oneof {
    int32 oneof_int32 = 1;
    int64 oneof_int64 = 2;
  }
}

Le compilateur génère les champs et la méthode spéciale suivants :

class TestMessage {
  private oneof_int32;
  private oneof_int64;
  public function getOneofInt32();
  public function setOneofInt32($var);
  public function getOneofInt64();
  public function setOneofInt64($var);
  public function getTestOneof();  // Return field name
}

Le nom de la méthode d'accesseur est basé sur le nom de la méthode d'accesseur et renvoie une valeur d'énumération représentant le champ de l'une d'elles actuellement définie.