protocolbuffers / protocolbuffers/protobuf

Modernize PHP output

Open
#29,418 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature request keep open php
Dominant language
C++
Stars
72k
Forks
16.3k
Avg merge
1d 17h
Merged PRs (30d)
140

Description

What language does this apply to?
If it's for proto2, proto3, or an edition? All 3
If it's a generated code change, what programming language? PHP

Describe the problem you are trying to solve.
The docs have some outdated notions on PHP language features. Furthermore, modern features like property hooks means the resulting code can be a lot easier to use without requiring consumers to read a PHP protobuf specific manual.

Describe the solution you'd like

Enums

PHP Now supports enums.

// Current
class TestEnum {
  const DEFAULT = 0;
  const A = 1;
}

// Desired
enum TestEnum: int {
    case DEFAULT = 0;
    case A = 1;
}

Property hooks

PHP now supports property hooks, this means that much of the custom instrumentation can be simplified.
For example, here's an extract of a generated class from Opentelemetry, a LogRecord

class LogRecord extends \Google\Protobuf\Internal\Message {
   public function __construct($data = NULL) {
        \GPBMetadata\Opentelemetry\Proto\Logs\V1\Logs::initOnce();
        parent::__construct($data);
    }
    

    public function getTimeUnixNano()
    {
        return $this->time_unix_nano;
    }

    /**
     * time_unix_nano is the time when the event occurred.
     * Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.
     * Value of 0 indicates unknown or missing timestamp.
     *
     * Generated from protobuf field <code>fixed64 time_unix_nano = 1;</code>
     * @param int|string $var
     * @return $this
     */
    public function setTimeUnixNano($var)
    {
        GPBUtil::checkUint64($var);
        $this->time_unix_nano = $var;

        return $this;
    }

}

With property hooks we can simplify this:

class LogRecord extends \Google\Protobuf\Internal\Message {
    /**
     * time_unix_nano is the time when the event occurred.
     * Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.
     * Value of 0 indicates unknown or missing timestamp.
     *
     * Generated from protobuf field <code>fixed64 time_unix_nano = 1;</code>
     * @return int|string
     */
    protected int $time_unix_nano = 0 {
        set(int|string $value) {
            GPBUtil::checkUint64($value);
            $this->time_unix_nano = $value
        }
    };

    public function __construct($data = NULL) {
        \GPBMetadata\Opentelemetry\Proto\Logs\V1\Logs::initOnce();
        parent::__construct($data);
    }
}

Consuming the code in userland then becomes a lot more "native":

$logRecord = new LogRecord();
$logRecord->xxx = 12345;
$logRecord->yyy = 12345;
$logRecord->zzz[] = "additional value";

Repeated fields

Since we're generating code, for repeated fields we could also introduce simple collection objects. This removes the need for a get, modify, set.

Describe alternatives you've considered
These are just some ideas to modernize the generated code. Functionally today's code works, but it doesn't take advantage of modern PHP language features like enums, property hooks and typing that could improve the developer experience.

Additional context
I'd propose something like a php-modern compilation target that targets php 8.5 x64.
From PHP 9 onwards dropping 32 bit versions altogether is being considered. I'd argue that even now for a modern compilation target, the special uInt64 checks can be simplified even further, or just rely on the PHP type system.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No source files, entry points, or tests are named. Start by locating the PHP generator and its generated-code tests, then compare current output with the proposed PHP 8.5 target for enums, property hooks, typing, and repeated fields. Done requires an agreed scope and compatibility criteria for the modern compilation target.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.