Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use PHP-YAML's custom tag callbacks?

Tags:

php

yaml

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_STYLE constant.
  • The return value of callbacks replaces the tagged data structure

Can anyone confirm the expected behavior of this function?

like image 772
Austin Hyde Avatar asked Oct 11 '22 16:10

Austin Hyde


1 Answers

After much research and testing, I have found some answers.

As found in the extension's unit tests, each callback takes three arguments:

  • mixed $data - The tagged data, already parsed
  • string $tag - The tag name, expanded according to the offical YAML tag specs:
    • !custom expands to !custom if no tag prefix is defined
    • !custom expands to prefixcustom, where prefix is defined by the document meta-data %TAG ! prefix. Note there is not a leading exclamation mark
    • !!preset expands to the parser-defined internal type. See the YAML_*_TAG constants
    • !<verbatim-tag> expands toverbatim-tag`. Note there is not a leading exclamation mark.
  • integer $style - The scalar style used. See the YAML_*_SCALAR_STYLE constants

The callback should return a mixed value for the parser to emit.

like image 61
Austin Hyde Avatar answered Nov 01 '22 16:11

Austin Hyde