According to the official documentation, there is a way to provide callbacks for custom YAML tags:
mixed yaml_parse ( string $input [, int $pos = 0 [, int &$ndocs [, array $callbacks ]]] )
callbacks
Content handlers for YAML nodes. Associative array of YAML tag => callback mappings.
However, there seems to be no other documentation on the subject, even in the extension source!
I created this script as a test:
<?php
$yaml =<<<YAML
---
prop: !custom val
YAML;
print_r(yaml_parse($yaml,0,$n,array(
YAML_STR_TAG => function () {
echo "YAML_STR_TAG\n";
$args = func_get_args();
print_r($args);
return 'x';
},
'!custom' => function () {
echo "!custom\n";
$args = func_get_args();
print_r($args);
return 'y';
}
)));
And I got this output:
$ php yaml.php
YAML_STR_TAG
Array
(
[0] => prop
[1] => tag:yaml.org,2002:str
[2] => 1
)
!custom
Array
(
[0] => val
[1] => !custom
[2] => 1
)
Array
(
[x] => y
)
From that I can tell several things:
- The key used in the callback lookup is either one of PHP-YAML’s predefined constants or the custom tag used in the YAML source, including the exclamation point
- Each key and value in a map gets “tagged” and passed to the matching callback, probably because according to the YAML spec the key can be any valid type as well.
- Three arguments are passed to the callback: the “subject” of the tag, the tag itself, and some number, probably corresponding to a
YAML_*_SCALAR_STYLEconstant. - The return value of callbacks replaces the tagged data structure
Can anyone confirm the expected behavior of this function?
After much research and testing, I have found some answers.
As found in the extension’s unit tests, each callback takes three arguments:
$data– The tagged data, already parsed$tag– The tag name, expanded according to the offical YAML tag specs:!customexpands to!customif no tag prefix is defined!customexpands toprefixcustom, whereprefixis defined by the document meta-data%TAG ! prefix. Note there is not a leading exclamation mark!!presetexpands to the parser-defined internal type. See theYAML_*_TAGconstants!<verbatim-tag> expands toverbatim-tag`. Note there is not a leading exclamation mark.$style– The scalar style used. See theYAML_*_SCALAR_STYLEconstantsThe callback should return a mixed value for the parser to emit.