Protobuf: Undefined Index Notice - PHP

Created on 21 Feb 2017  Â·  29Comments  Â·  Source: protocolbuffers/protobuf

I'm getting PHP notices for a lot of my types, not sure why.

PHP Notice:  Undefined index: .foo.bar.baz in /Users/trent/src/github.com/sajari/phptest/vendor/google/protobuf/php/src/Google/Protobuf/Internal/DescriptorPool.php on line 125
php

Most helpful comment

@TeBoring: This is still happening. It's due to the fact that enum types nested inside messages aren't being registered correctly in the descriptor pool.

message TestRequest {
  enum TestEnum {
    ZERO = 0;
    ONE = 1;
  }

  string name = 1;

  TestEnum test_enum = 2;
}

The TestEnum enum is being generated as \SimpleTest\TestRequest_TestEnum, yet there's no record of it in anything internal to DescriptorPool. This leads me to believe that there's either a bug or an unhandled valid case in descriptor.php. This is almost certainly a bug in the protobuf syntax parser, and I'd really appreciate if you could give it some priority, as it's not treating valid protobuf syntax correctly.

All 29 comments

which version are u using?
On Mon, Feb 20, 2017 at 20:26 tbillington notifications@github.com wrote:

I'm getting PHP notices for a lot of my types, not sure why.

PHP Notice: Undefined index: .foo.bar.baz in /Users/trent/src/github.com/sajari/phptest/vendor/google/protobuf/php/src/Google/Protobuf/Internal/DescriptorPool.php on line 125

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/google/protobuf/issues/2743, or mute the thread
https://github.com/notifications/unsubscribe-auth/AE9H5Zi0h8uQQw7dzS4N8sbUrr4GaVbzks5remdjgaJpZM4MG3d8
.

php grpc library: "grpc/grpc": "v1.1.2"
protoc: libprotoc 3.2.0

Just got the grpc_php_plugin from master a few hours ago.

Have you used protoc to generate code?
On Mon, Feb 20, 2017 at 21:08 tbillington notifications@github.com wrote:

php grpc library: "grpc/grpc": "v1.1.2"
protoc: libprotoc 3.2.0

Just got the grpc_php_plugin from master a few hours ago.

—
You are receiving this because you commented.

Reply to this email directly, view it on GitHub
https://github.com/google/protobuf/issues/2743#issuecomment-281246783,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AE9H5WurnUtMbOwdFoePG5D_qXoMwg-rks5renFWgaJpZM4MG3d8
.

Yup

protoc -I$PROTO_SRC --php_out=$dest --grpc_out=$dest --plugin=protoc-gen-grpc=/Users/trent/grpc/bins/opt/grpc_php_plugin $dir/*.proto

What's the protoc version?
And did you autoload your generated proto files?
On Mon, Feb 20, 2017 at 21:50 tbillington notifications@github.com wrote:

Yup

protoc -I$PROTO_SRC --php_out=$dest --grpc_out=$dest --plugin=protoc-gen-grpc=/Users/trent/grpc/bins/opt/grpc_php_plugin $dir/*.proto

—
You are receiving this because you commented.

Reply to this email directly, view it on GitHub
https://github.com/google/protobuf/issues/2743#issuecomment-281251578,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AE9H5S3iv8XgEubbIUNVJilJpE7srXwFks5rensTgaJpZM4MG3d8
.

Yes, I autoloaded. I posted just before your previous comment the protoc version (maybe harder to see in email): libprotoc 3.2.0

Can I see your proto file and test code?

Seems this is only happening on enums.

Maybe it can be fixed in you have a non-empty namespace. Let me know if it works.

Still had the issue in a non-empty namespace.

Here is some test code that demonstrates the issue. I removed the namespace because it had no impact.

Proto File:

syntax = "proto3";

package simpletest;

service SimpleTest {
  rpc Test (TestRequest) returns (TestResponse);
}

message TestRequest {
  enum TestEnum {
    ZERO = 0;
    ONE = 1;
  }

  string name = 1;

  TestEnum test_enum = 2;
}

message TestResponse {
  string reply = 1;
}

Test Code:

<?php

require  __DIR__ . "/vendor/autoload.php";

include_once  __DIR__ . "/proto/SimpleTest/SimpleTestClient.php";
include_once  __DIR__ . "/proto/SimpleTest/TestRequest.php";
include_once  __DIR__ . "/proto/SimpleTest/TestRequest_TestEnum.php";
include_once  __DIR__ . "/proto/SimpleTest/TestResponse.php";
include_once  __DIR__ . "/proto/GPBMetadata/Messages.php";

$client = new SimpleTest\SimpleTestClient("localhost:1111", ['credentials' => Grpc\ChannelCredentials::createInsecure()]);

$req = new SimpleTest\TestRequest();
$req->setName("Foo");
$req->setTestEnum(SimpleTest\TestRequest_TestEnum::ONE);

try {
    list($res, $status) = $client->Test($req)->wait();
    printf("%s\n", $res->getReply());
} catch (Exception $e) {
    printf("%s\n", $e);
}

Output:

PHP Notice:  Undefined index: .simpletest.TestRequest.TestEnum in /Users/trent/src/github.com/sajari/proto-php-example/vendor/google/protobuf/php/src/Google/Protobuf/Internal/DescriptorPool.php on line 125

Notice: Undefined index: .simpletest.TestRequest.TestEnum in /Users/trent/src/github.com/sajari/proto-php-example/vendor/google/protobuf/php/src/Google/Protobuf/Internal/DescriptorPool.php on line 125
PHP Notice:  Undefined index:  in /Users/trent/src/github.com/sajari/proto-php-example/vendor/google/protobuf/php/src/Google/Protobuf/Internal/DescriptorPool.php on line 126

Notice: Undefined index:  in /Users/trent/src/github.com/sajari/proto-php-example/vendor/google/protobuf/php/src/Google/Protobuf/Internal/DescriptorPool.php on line 126
Hello Foo!

@TeBoring: This is still happening. It's due to the fact that enum types nested inside messages aren't being registered correctly in the descriptor pool.

message TestRequest {
  enum TestEnum {
    ZERO = 0;
    ONE = 1;
  }

  string name = 1;

  TestEnum test_enum = 2;
}

The TestEnum enum is being generated as \SimpleTest\TestRequest_TestEnum, yet there's no record of it in anything internal to DescriptorPool. This leads me to believe that there's either a bug or an unhandled valid case in descriptor.php. This is almost certainly a bug in the protobuf syntax parser, and I'd really appreciate if you could give it some priority, as it's not treating valid protobuf syntax correctly.

Also, following on from this, there's no test for this situation in https://github.com/google/protobuf/blob/d9e0119f2c2f49ea89012a03c030e2b5011d0bc3/php/tests/proto/test.proto, which I would expect to fail here.

@TeBoring any progress on this?

Sorry, I don't have time to work on this yet. But I do want to include the fix in the 3.3 release. @mcos Could you send a fix?

@mcos @TeBoring I'm having the same issue. It seems that nested enums inside messages are not being parsed correctly. I believe this is happening at \Google\Protobuf\Internal\FileDescriptor::buildFromProto($proto). It seems that only the messages/enums in the top level are being parsed. Shouldn't this be a recursive function to be able to parse types for more than 1 level based on the .proto file ?

Added test in #2989. However, I don't find the bug. @mcos, @svdev, could you verify?
BTW, grpc may depend on old version of protobuf. The latest changes for php is in 3.3.x branch.

@TeBoring My issue was that I didn't specify a package statement in each .proto file so the descriptor had loaded all the nested enums classes but with an incorrect namespace. For instance, my generated classes were trying to load \MyPackage\.MyMessage_MyEnumClass.php but they were registered by the descriptor pool as .MyMessage_MyEnumClass.php .

After specifying the package in each .proto file I'm able to load all nested enum/messages classes correctly.

Could you paste your proto?

test_no_namespace.proto should have covered your case.

I'm having the same issue and this post is a little bit confused for me: @TeBoring it is a bug or not?

I have downloaded protobuf 3.2 via composer and run the php test: generated_class_test.php, everything is fine.

My protoc version ist also: libprotoc 3.2.0

I then changed the file test_no_namespace.proto and generated the php files via the same command

syntax = "proto3";

message NoNameSpaceMessage {
int32 a = 1;

enum NestedEnum {
ZERO = 0;
}
NestedEnum b = 2;
}

enum NoNameSpaceEnum {
VALUE_A = 0;
VALUE_B = 1;
}

I try to run the generated_class_test.php, but firstly I got

PHP Parse error: syntax error, unexpected '\' (T_NS_SEPARATOR), expecting identifier (T_STRING) in /var/www/html/devel/src/vendor/google/protobuf/php/tests/generated/NoNameSpaceMessage.php on line 58

I changed the following code
image
to
image

and try to run the test file: generated_class_test.php

Now, I got:
image

Maybe I have done something wrong?

I tried with protobuf 3.3.0 from the 3.3.x branch. I got errors when I try to run the test generated_class_test.php

image

All errors are the same: Undefined index: .NoNamespaceMessage.NestedEnum

@TeBoring Could you please verify? And I'd really appreciate if you could give it some priority.

@FrechNina I don't see the error you found. All our test are passed before being merged.

@FrechNina Could you tell me how to do the test? From where to download the code and how to trigger it.

Before doing test, you need to:
1) compile protoc
2) use protoc to generate code.

@FrechNina, for compiling the protoc:
1) git clone https://github.com/google/protobuf.git
2) cd protobuf; git checkout 3.3.x
3) Follow https://github.com/google/protobuf/tree/master/src

Feel free to reopen if there is still bug.

@TeBoring I have completely reinstalled the library. Unfortunately, I got the same errors.

The commands I used:

git clone https://github.com/google/protobuf.git
cd protobuf
git checkout 3.3.x

sudo apt-get install autoconf automake libtool curl make g++ unzip
./autogen.sh
./configure --prefix=/usr
make
make check # All 7 tests passed
sudo make install
sudo ldconfig

protoc --version #libprotoc 3.3.0
which protoc #/usr/bin/protoc
cd php
composer install
cd tests/
mkdir generated
protoc --php_out=generated proto/*.proto
cd ..
vendor/bin/phpunit tests/generated_class_test.php

If you need any of my system info, please let me know.

BTW, if I have commented the nested enum definations in the .proto files and the related test code in the generated_class_test.php, then all tests passed.

Should have been fixed in #3009

Was this page helpful?
0 / 5 - 0 ratings