如何将PHP Protobuf对象转换为JSON字符串

3
我希望使用PHP将我的Protobuf对象转换为JSON对象,以便可以将其发送回浏览器。
我的Protobuf是:
syntax = "proto3";
package Protobuf.Gen.ProposalTotalModel;
option php_generic_services = true;

message ProposalTotal {

  message Total {
    double static = 1;
    double hourly = 2;
    double monthly = 3;
    double annual = 4;
  }

  message TotalAfterTax {
    double static = 1;
    double hourly = 2;
    double monthly = 3;
    double annual = 4;
  }

  Total total = 1;
  TotalAfterTax total_after_tax = 2;
  bool has_totals = 3;
}

从上面的文件生成的protobuf代码(跳过其他自动生成的文件):

<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: proposal_total.proto

namespace Protobuf\Gen\ProposalTotalModel;

use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;

/**
 * Generated from protobuf message <code>Protobuf.Gen.ProposalTotalModel.ProposalTotal</code>
 */
class ProposalTotal extends \Google\Protobuf\Internal\Message
{
    /**
     * Generated from protobuf field <code>.Protobuf.Gen.ProposalTotalModel.ProposalTotal.Total total = 1;</code>
     */
    private $total = null;
    /**
     * Generated from protobuf field <code>.Protobuf.Gen.ProposalTotalModel.ProposalTotal.TotalAfterTax total_after_tax = 2;</code>
     */
    private $total_after_tax = null;
    /**
     * Generated from protobuf field <code>bool has_totals = 3;</code>
     */
    private $has_totals = false;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type \Protobuf\Gen\ProposalTotalModel\ProposalTotal\Total $total
     *     @type \Protobuf\Gen\ProposalTotalModel\ProposalTotal\TotalAfterTax $total_after_tax
     *     @type bool $has_totals
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\ProposalTotal::initOnce();
        parent::__construct($data);
    }

    /**
     * Generated from protobuf field <code>.Protobuf.Gen.ProposalTotalModel.ProposalTotal.Total total = 1;</code>
     * @return \Protobuf\Gen\ProposalTotalModel\ProposalTotal\Total
     */
    public function getTotal()
    {
        return $this->total;
    }

    /**
     * Generated from protobuf field <code>.Protobuf.Gen.ProposalTotalModel.ProposalTotal.Total total = 1;</code>
     * @param \Protobuf\Gen\ProposalTotalModel\ProposalTotal\Total $var
     * @return $this
     */
    public function setTotal($var)
    {
        GPBUtil::checkMessage($var, \Protobuf\Gen\ProposalTotalModel\ProposalTotal_Total::class);
        $this->total = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>.Protobuf.Gen.ProposalTotalModel.ProposalTotal.TotalAfterTax total_after_tax = 2;</code>
     * @return \Protobuf\Gen\ProposalTotalModel\ProposalTotal\TotalAfterTax
     */
    public function getTotalAfterTax()
    {
        return $this->total_after_tax;
    }

    /**
     * Generated from protobuf field <code>.Protobuf.Gen.ProposalTotalModel.ProposalTotal.TotalAfterTax total_after_tax = 2;</code>
     * @param \Protobuf\Gen\ProposalTotalModel\ProposalTotal\TotalAfterTax $var
     * @return $this
     */
    public function setTotalAfterTax($var)
    {
        GPBUtil::checkMessage($var, \Protobuf\Gen\ProposalTotalModel\ProposalTotal_TotalAfterTax::class);
        $this->total_after_tax = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>bool has_totals = 3;</code>
     * @return bool
     */
    public function getHasTotals()
    {
        return $this->has_totals;
    }

    /**
     * Generated from protobuf field <code>bool has_totals = 3;</code>
     * @param bool $var
     * @return $this
     */
    public function setHasTotals($var)
    {
        GPBUtil::checkBool($var);
        $this->has_totals = $var;

        return $this;
    }

}

我能够将我的 JSON 对象转换为 Protobuf 对象,并在进行 POST 请求时将其存储在 Redis 中。
$total = new \Protobuf\Gen\ProposalTotalModel\ProposalTotal( );
$total->mergeFromJsonString( $body, false );

然后,对于一个GET请求,我想取出存储在Redis中的这个对象并将其发送回客户端。我知道在其他语言中,我们可以使用JsonFormat.printer().print(obj);。但是我没有找到类似的PHP功能来实现。是否可以自动生成JSON或者我必须通过获取Protobuf对象中的所有getter字段来手动构造JSON?由于生成的Php文件属性是私有的,所以json_encode不适用。
1个回答

4

使用 $total->serializeToJsonString()。我在 Laravel 中尝试过,它可以工作。这是一个示例代码

这非常类似于:

JsonFormat.printer().print(myBuiltProtoObject);

Route::get('/rpc', function () {
    // include_once '../protos/Person.php';
    $aBook = new AddressBook();
    $aBook->setPerson([
        (function () {
            $p = new Person();

            $p->setName('Helloname');
            $p->setId(10015);

            $p->setPhone([
                (function () {
                    $pn = new PhoneNumber();
                    $pn->setNumber('6281284842477');
                    $pn->setType(PhoneType::MOBILE);

                    return $pn;
                })(),
                (function () {
                    $pn = new PhoneNumber();
                    $pn->setNumber('62215501728');
                    $pn->setType(PhoneType::WORK);

                    return $pn;
                })(),
            ]);

            return $p;
        })(),
        (function () {
            $p2 = new Person();
            $p2->setName('Masdani');
            $p2->setId(10016);

            return $p2;
        })()
    ]);

    return response()->json(json_decode($aBook->serializeToJsonString()));
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接