【问题标题】:How to convert PHP Protobuf Object to a JSON string如何将 PHP Protobuf 对象转换为 JSON 字符串
【发布时间】:2021-07-29 09:55:44
【问题描述】:

我想使用 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;
    }

}

在执行POST 请求时,我能够将我的 JSON 对象转换为 Protobuf 对象以存储在 Redis 中

$total = new \Protobuf\Gen\ProposalTotalModel\ProposalTotal( );
$total->mergeFromJsonString( $body, false );

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

json_encode 超出范围,因为生成的 Php 文件属性是私有的。

【问题讨论】:

    标签: php json protocol-buffers proto protoc


    【解决方案1】:

    使用$total-&gt;serializeToJsonString()。我在 laravel 中尝试过,它可以工作 example code

    很像

    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()));
    });
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-03
      • 2018-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      相关资源
      最近更新 更多