如何在PHP中正确解包任何类型的Protobuf

如何在PHP中正确解包任何类型的Protobuf,php,protocol-buffers,Php,Protocol Buffers,我拼命想检查Any中包装的“未知”protobuf负载是否是某种特定类型(Heartbeat),并使用下面的代码将其解压缩到Heartbeat对象。Heartbeat和StatusChanged都是有效生成的Protobuf类 /**/ $event=(新状态已更改)->setId(“testId”); $any=新的any; $any->pack($event); $protobufBinaryAny=$any->serializeToString(); /* */ /*$protobufB

我拼命想检查
Any
中包装的“未知”protobuf负载是否是某种特定类型(
Heartbeat
),并使用下面的代码将其解压缩到Heartbeat对象。
Heartbeat
StatusChanged
都是有效生成的Protobuf类

/**/
$event=(新状态已更改)->setId(“testId”);
$any=新的any;
$any->pack($event);
$protobufBinaryAny=$any->serializeToString();
/*  */
/*$protobufBinaryAny是传入的二进制数据*/
$anyEvent=newany();
$anyEvent->mergeFromString($protobufBinaryAny);
如果($anyEvent->is(Heartbeat::class)){
$this->processHeartbeat($anyEvent->unpack());
}否则{
抛出新的UnknownMessageTypeException($anyEvent->getTypeUrl());
}
在运行以下代码时,我希望它抛出一个未知的NMessageTypeException,但是,我发现:

Call to a member function getFullName() on null.
此错误发生在
$data->is(Heartbeat::class)
,因为在
描述符工具中显然找不到Heartbeat类

/**
*谷歌\Protobuf\Any
* https://github.com/protocolbuffers/protobuf/blob/440a156e1cd5c783d8d64eef81a93b1df3d78b60/php/src/Google/Protobuf/Any.php#L315-L323
*/
任何类别{
公共职能是($klass)
{
$pool=\Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
$desc=$pool->getDescriptorByCassName($klass);
$fully_qualifed_name=$desc->getFullName();
$type\u url=GPBUtil::type\u url\u PREFIX.substr(
$fully_qualified_name,1,strlen($fully_qualified_name));
返回$this->type\u url===$type\u url;
}
}
但是,在之前显式初始化Heartbeat时,它正在工作,因为
Heartbeat
现在位于描述符工具中

foreach([
\GPBMetadata\Heartbeat::类,
\GPBMetadata\StatusChanged::类,
]as$klass){
$klass::initOnce();
}
但是这个手动初始化的东西感觉不对。我是应该这样做,还是只是错过了不存在的PHP文档中的一个奇特的自动加载功能

目前,我为这个案例写了一个自动加载器,但感觉还是不对:

trait HandlesProtobufMessages
{
函数initializeProtobufMessages()
{
/**@var\Composer\Autoload\ClassLoader*/
$loader=require(_DIR__.'/../../vendor/autoload.php');
$classes=array\u过滤器(array\u键($loader->getClassMap()),函数($className){
$namespace=“GPBMetadata\\”;
返回substr($className,0,strlen($namespace))=$namespace;
});
foreach($classes作为$class){
$class::initOnce();
}
}
}
也许你对这个原始丛林有更多的了解,能在这里帮助我,我会很高兴的

先谢谢你