php / pecl-file_formats-yaml

YAML-1.1 parser and emitter
https://pecl.php.net/package/yaml
MIT License
71 stars 33 forks source link

How to output explicit object by yaml_emit() #70

Open HJ-fukura opened 2 years ago

HJ-fukura commented 2 years ago

json_encode() can ouptut empty object, but yaml_emit() cannot. Please tell me how to output empty object like {}.

tested with versions:

php 8.1.8 (Windows x86_64) php_yaml-2.2.2-8.1-nts-vs16-x64.zip

<?php
    $a = [
        'int'        => 123,
        'string'     => 'aaa', 
        'array'      => [],
        'object_ok'  => ['a'=>123],
        'object_ng1' => (object)[],
        'object_ng2' => (object)['a'=>123],
    ];

    echo json_encode($a, JSON_PRETTY_PRINT), "\n", yaml_emit($a);

output:

{
    "int": 123,
    "string": "aaa",
    "array": [],
    "object_ok": {
        "a": 123
    },
    "object_ng1": {},
    "object_ng2": {
        "a": 123
    }
}
---
int: 123
string: aaa
array: []
object_ok:
  a: 123
object_ng1: !php/object "O:8:\"stdClass\":0:{}"
object_ng2: !php/object "O:8:\"stdClass\":1:{s:1:\"a\";i:123;}"
...
vaheen commented 2 years ago

Consider the following workaround to convert objects to arrays

echo yaml_emit(json_decode(json_encode($a),true));

output:

---
int: 123
string: aaa
array: []
object_ok:
  a: 123
object_ng1: []
object_ng2:
  a: 123
...
bd808 commented 1 year ago

I do not believe that the current implementation can be coerced into emitting {}.

The extension emits (most) objects as serialized data with an associated !php/object tag. The {} you want is an empty flow mapping. Both YAML mappings and sequences are generated for PHP arrays. If the array contains non-numeric keys or non-sequential numeric keys then it is emitted as a mapping, otherwise it is emitted as an array. An empty array will emit as an empty flow sequence ([]) and not an empty flow mapping ({}).

JohnRDOrazio commented 4 months ago

Perhaps an internal serialization of objects to associative arrays could be considered? It would make it that much easier to use...

JohnRDOrazio commented 4 months ago

I'm seeing that there is an ini setting for decoding serialized objects yaml.decode_php=1. Perhaps there could be a similar setting for encoding serialized objects yaml.encode_php=1?