OBSERVAÇÃO:este site foi descontinuado. O site será desativado após 31 de janeiro de 2023, e o tráfego será redirecionado para o novo site em https://protobuf.dev. Enquanto isso, as atualizações serão feitas apenas para protobuf.dev.

Código gerado por PHP

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Esta página descreve o código PHP que o compilador de buffer de protocolo gera para qualquer definição de protocolo. Leia o guia do idioma proto3 antes de ler este documento. No momento, o compilador de buffer de protocolo oferece suporte apenas à geração de código proto3 para PHP.

Invocação do compilador

O compilador de buffer de protocolo produz a saída PHP quando invocado com a sinalização de linha de comando --php_out=. O parâmetro para a opção --php_out= é o diretório em que você quer que o compilador grave a saída do PHP. Para se adequar à PSR-4, o compilador cria um subdiretório correspondente ao pacote definido no arquivo proto. Além disso, para cada mensagem na entrada do arquivo proto, o compilador cria um arquivo separado no subdiretório do pacote. Os nomes dos arquivos de saída das mensagens são compostos por três partes:

  • Diretório base: o caminho do proto (especificado com a sinalização de linha de comando --proto_path= ou -I) é substituído pelo caminho de saída (especificado com a sinalização --php_out=).
  • Subdiretório: . no nome do pacote foi substituído pelo separador de diretório do sistema operacional. Cada componente do nome do pacote fica em letras maiúsculas.
  • Arquivo: o nome da mensagem é anexado por .php.

Então, por exemplo, suponha que você invoque o compilador da seguinte forma:

protoc --proto_path=src --php_out=build/gen src/example.proto
E src/example.proto é definido como:
package foo.bar;
message MyMessage {}

O compilador vai ler os arquivos src/foo.proto e produzir o arquivo de saída: build/gen/Foo/Bar/MyMessage.php. O compilador criará automaticamente o diretório build/gen/Foo/Bar, se necessário, mas não criará build ou build/gen. Eles já devem existir.

Entrega de pacotes

O nome do pacote definido no arquivo .proto é usado para gerar uma estrutura de módulos para as classes PHP geradas. Dados de um arquivo como este:

package foo.bar;

message MyMessage {}

O compilador de protocolos gera uma classe de saída com o nome Foo\Bar\MyMessage.

Mensagens

Se a declaração for simples:

message Foo {}

O compilador de buffer de protocolo gera uma classe PHP chamada Foo. Essa classe herda de uma classe base comum, Google\Protobuf\Internal\Message, que fornece métodos para codificar e decodificar seus tipos de mensagens, como mostrado no exemplo a seguir:

$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.
  ...
}

Não crie suas próprias subclasses Foo. As classes geradas não são projetadas para criar subclasses e podem gerar problemas de "classe base frágil".

As mensagens aninhadas resultam em uma classe PHP com o mesmo nome precedida pela mensagem contida e separadas por sublinhados, já que o PHP não oferece suporte a classes aninhadas. Por exemplo, se você tiver o seguinte no seu .proto:

message TestMessage {
  optional int32 a = 1;
  message NestedMessage {...}
}
O compilador vai gerar as seguintes classes:
class TestMessage {
  public a;
}

// PHP doesn’t support nested classes.
class TestMessage_NestedMessage {...}
Se o nome da classe da mensagem estiver reservado (por exemplo, Empty), o prefixo PB vai ser anexado ao nome da classe:
class PBEmpty {...}
Também fornecemos a opção de nível de arquivo php_class_prefix. Se especificado, ele será anexado a todas as classes de mensagem geradas.

Campos

Para cada campo em um tipo de mensagem, há métodos do acessador para definir e receber o campo. Dessa forma, considerando um campo x, é possível escrever:

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

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

Sempre que você define um campo, o valor é verificado em relação ao tipo declarado desse campo. Se o valor for do tipo errado (ou estiver fora do intervalo), será gerada uma exceção. Por padrão, as conversões de tipo (por exemplo, ao atribuir um valor a um campo ou adicionar um elemento a um campo repetido) são permitidas a partir de strings de números inteiros, flutuantes e numéricos. As conversões não permitidas incluem todas as conversões de/para matrizes ou objetos. As conversões flutuantes para número inteiro são indefinidas.

Você pode ver o tipo de PHP correspondente para cada tipo de buffer de protocolo escalar na tabela de tipos de valor escalar.

Campos de mensagens individuais

Um campo com tipo de mensagem assume como padrão o valor nulo e não é criado automaticamente quando o campo é acessado. Portanto, você precisa criar explicitamente as submensagens, como a seguinte:

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

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

É possível atribuir qualquer instância a um campo de mensagem, mesmo que ela também esteja retida em outro lugar (por exemplo, como um valor de campo em outra mensagem).

Campos repetidos

O compilador de buffer de protocolo gera um RepeatedField especial para cada campo repetido. Por exemplo, considerando o campo a seguir:

repeated int32 foo = 1;
O código gerado permite fazer isso:
$m->getFoo()[] =1;
$m->setFoo($array);

Campos do mapa

O compilador de buffer de protocolo gera um MapField para cada campo do mapa. Então, conforme este campo:

map<int32, int32> weight = 1;

É possível fazer o seguinte com o código gerado:

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

Enumerações

O PHP não tem enumerações nativas. Portanto, o compilador de buffer de protocolo gera uma classe PHP para cada tipo de enum no arquivo .proto, assim como para messages, com constantes definidas para cada valor. Considerando esse tipo enumerado:
enum TestEnum {
  Default = 0;
  A = 1;
}
O compilador gera a seguinte classe:
class TestEnum {
  const DEFAULT = 0;
  const A = 1;
}
Além disso, com as mensagens, uma enumeração aninhada resultará em uma classe PHP com o mesmo nome, usando as mensagens e separadas por sublinhados, já que o PHP não oferece suporte a classes aninhadas.
class TestMessage_NestedEnum {...}
Se uma classe de enumeração ou nome de valor for reservado (por exemplo, Empty), o prefixo PB será anexado ao nome da classe ou do valor:
class PBEmpty {
  const PBECHO = 0;
}
Também fornecemos a opção de nível de arquivo php_class_prefix. Se especificado, ele é anexado a todas as classes de enumeração geradas.

Oneof

Para oneofs, o compilador de buffer de protocolo gera o mesmo código que faria para campos singulares normais, mas também adiciona um método de acessador especial que permite descobrir qual campo (se houver) está definido. Portanto, considerando esta mensagem:

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

O compilador gera os seguintes campos e método especial:

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
}

O nome do método do acessador é baseado no nome do método e retorna um valor de enumeração que representa o campo no que está definido no momento.