allegro / php-protobuf

PHP Protobuf - Google's Protocol Buffers for PHP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Big Number Error

Balowser opened this issue · comments

I have a big Number (2069643420177269543) which will not be displayed correct.
After a "parseFromString", I only get the Number 807..

Some Ideas why?

The internal representation of integer type in PHP is C long type. It's range is [−9,223,372,036,854,775,807, +9,223,372,036,854,775,807] for 64-bit platforms. The value you try to deserialize is out of this range. If you are of control of proto file and don't do any arithmetic operations with the big number I would suggest to change the field type to string.

If you do that php-protobuf won't be able to deserialized a message because it will expect a field to be of type of string whereas it will be of number type. You need to change the type in the proto file and recompile it for all languages you use.

It means the protobuf expects field to be a string (length delimited) but it's a number (varint). It seems you updated only the one side - the PHP's and left the other untouched.

Now I see I miscounted the digits in your big number - it's within the C long type range. What .proto type is used for the filed holding big number?

Hello,

in the .proto File is used:
sint64 nr_id= 0x0001;

Thanks!

I tried the following.

.proto file:

syntax = "proto2";

message Foo
{
    required sint64 nr_id= 0x0001;
}

PHP script:

require 'Foo.php';

$foo = new Foo();
$foo->setNrId(2069643420177269543);
$pack = $foo->serializeToString();
$unpackedFoo = new Foo();
$unpackedFoo->parseFromString($pack);
var_dump($unpackedFoo->getNrId());

Output:

int(2069643420177269543)

The big number is deserialized correctly.

Moreover I when I try to deserialize the big number serialized by official Google's python implementation I get the correct result.

Can you provide a code snippet that you reproduce with the issue you are facing?

I called the Api without Protobuf and got:
nr_id: 1069643420177269543

The Proto:

    message StopTdi {
        sint64 nr_id= 0x0001;
       }

The Php-File:


require 'measure.php';

$mea= new measure();
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "url" );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_HTTPHEADER,     array('Accept: application/x-protobuf')); 
$result=curl_exec ($ch);
$mea= new measure();
try {
    $mea->parseFromString($result);
} catch (Exception $ex) {
    die('Parse error: ' . $e->getMessage());
}
foreach ($mea->getmea as $key => $value)
{
	
	echo "nr: ".$value->getnrId();
}

I Got:
nr: 807

Can you show me base64-encoded $result so I can check it?

It turns out the extension was used on x86 platform where PHP's integer type is 32bits.