Description
PHP avro serialising doesn't appear to support "optional" fields in records.
Consider the PHP script below:
<?php require_once('lib/avro.php'); $schema_json = <<<_JSON {"name":"member", "type":"record", "fields":[{"name":"one", "type":"int"}, {"name":"two", "type":["null", "string"]} ]} _JSON; $schema = AvroSchema::parse($schema_json); // Our datum is missing the 'optional' field (i.e. it's null) $datum = array("one" => 1); $io = new AvroStringIO(); $writer = new AvroIODatumWriter($schema); $encoder = new AvroIOBinaryEncoder($io); $writer->write($datum, $encoder); $bin = $io->string(); echo bin2hex($bin) . "\n";
My understanding from documentation is that this should work and output the encoded binary in hex.
Instead it throws:
PHP Fatal error: Uncaught exception 'AvroIOTypeException' with message 'The datum array ( 'one' => 1, ) is not an example of schema {"type":"record","name":"member","fields":[{"name":"one","type":"int"},{"name":"two","type":["null","string"]}]}'
It's possible that this is not a valid usage of Avro and I'm mistaken in my expectations, so I tried the python library as a comparison. Sure enough the following script works as expected:
from avro import schema from avro import io from StringIO import StringIO s = schema.parse(""" {"name":"member", "type":"record", "fields":[{"name":"one", "type":"int"}, {"name":"two", "type":["null", "string"]} ]}""") writer = StringIO() encoder = io.BinaryEncoder(writer) datum_writer = io.DatumWriter(s) datum_writer.write({"one": 1}, encoder) print writer.getvalue().encode("hex")
which outputs:
$ python avro_test.py 0200
As expected.