localheinz/json-normalizer

此包已被弃用且不再维护。作者建议使用ergebnis/json-normalizer包。

提供通用的和供应商特定的标准化器,用于标准化JSON文档。

4.5.0 2024-01-30 09:10 UTC

README

Integrate Merge Release Renew Update

Code Coverage Type Coverage

Latest Stable Version Total Downloads Monthly Downloads

此项目提供了一个带有通用和供应商特定标准化器的 composer 包,用于标准化 JSON文档

安装

运行

composer require ergebnis/json-normalizer

使用

此项目包含

通用标准化器

此项目包含以下通用标准化器

💡 所有这些标准化器都实现了 Ergebnis\Json\Normalizer\Normalizer

CallableNormalizer

当您想使用可调用函数标准化JSON文件时,可以使用CallableNormalizer

<?php

declare(strict_types=1);

use Ergebnis\Json\Json;
use Ergebnis\Json\Normalizer;

$encoded = <<<'JSON'
{
    "name": "Andreas Möller",
    "url": "https://localheinz.com"
}
JSON;

$json = Json::fromString($encoded);

$callable = function (Json $json): Json {
    $decoded = $json->decoded();

    foreach (get_object_vars($decoded) as $name => $value) {
        if ('https://localheinz.com' !== $value) {
            continue;
        }

        $decoded->{$name} .= '/open-source/';
    }

    return Json::fromString(json_encode($decoded));
};

$normalizer = new Normalizer\CallableNormalizer($callable);

$normalized = $normalizer->normalize($json);

标准化后的版本现在将应用可调用函数。

ChainNormalizer

当您想按链式应用多个标准化器时,可以使用ChainNormalizer

<?php

declare(strict_types=1);

use Ergebnis\Json\Json;
use Ergebnis\Json\Normalizer;
use Ergebnis\Json\Printer;

$encoded = <<<'JSON'
{
    "name": "Andreas Möller",
    "url": "https://localheinz.com"
}
JSON;

$json = Json::fromString($encoded);

$indent = Normalizer\Format\Indent::fromString('  ');
$jsonEncodeOptions = Normalizer\Format\JsonEncodeOptions::fromInt(JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

$normalizer = new Normalizer\ChainNormalizer(
    new Normalizer\JsonEncodeNormalizer($jsonEncodeOptions),
    new Normalizer\IndentNormalizer(
        $indent,
        new Printer\Printer()
    ),
    new Normalizer\WithFinalNewLineNormalizer()
);

$normalized = $normalizer->normalize($json);

标准化后的版本现在将包含按顺序应用所有标准化器的结果。

💡 注意标准化器的顺序,因为一个标准化器可能会覆盖上一个标准化器应用的变化。

FormatNormalizer

当您想使用格式标准化JSON文件时,可以使用FormatNormalizer

<?php

declare(strict_types=1);

use Ergebnis\Json\Json;
use Ergebnis\Json\Normalizer;
use Ergebnis\Json\Printer;

$encoded = <<<'JSON'
{
    "name": "Andreas Möller",
    "emoji": "🤓",
    "url": "https://localheinz.com"
}
JSON;

$json = Json::fromString($encoded);

$format = Normalizer\Format\Format::create(
    Normalizer\Format\Indent::fromString('  '),
    Normalizer\Format\JsonEncodeOptions::fromInt(JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
    Normalizer\Format\NewLine::fromString("\r\n")
    true
);

$normalizer = new Normalizer\FormatNormalizer(
    new Printer\Printer(),
    $format,
);

$normalized = $normalizer->normalize($json);

标准化后的版本现在将根据$format应用格式。

IndentNormalizer

当您需要调整JSON文件的缩进时,可以使用IndentNormalizer

<?php

declare(strict_types=1);

use Ergebnis\Json\Json;
use Ergebnis\Json\Normalizer;
use Ergebnis\Json\Printer;

$encoded = <<<'JSON'
{
    "name": "Andreas Möller",
    "url": "https://localheinz.com"
}
JSON;

$json = Json::fromString($encoded);

$indent = Normalizer\Format\Indent::fromString('  ');

$normalizer = new Normalizer\IndentNormalizer(
    $indent,
    new Printer\Printer()
);

$normalized = $normalizer->normalize($json);

标准化后的版本现在将使用2个空格缩进。

JsonEncodeNormalizer

当您需要调整JSON文件的编码时,可以使用JsonEncodeNormalizer

<?php

declare(strict_types=1);

use Ergebnis\Json\Json;
use Ergebnis\Json\Normalizer;

$encoded = <<<'JSON'
{
    "name": "Andreas M\u00f6ller",
    "url": "https:\/\/localheinz.com"
}
JSON;

$json = Json::fromString($encoded);

$jsonEncodeOptions = Normalizer\Format\JsonEncodeOptions::fromInt(JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

$normalizer = new Normalizer\JsonEncodeNormalizer($jsonEncodeOptions);

$normalized = $normalizer->normalize($json);

标准化后的版本现在将使用$jsonEncodeOptions进行编码。

💡 参考文档,请查看 json_encode() 和相应的 JSON 常量

SchemaNormalizer

当您想根据JSON模式重建JSON文件时,可以使用SchemaNormalizer

假设以下模式

{
    "type": "object",
    "additionalProperties": true,
    "properties": {
        "name" : {
            "type" : "string"
        },
        "role" : {
            "type" : "string"
        }
    }
}

位于/schema/example.json

<?php

declare(strict_types=1);

use Ergebnis\Json\Normalizer;
use Ergebnis\Json\Pointer;
use Ergebnis\Json\SchemaValidator;
use JsonSchema\SchemaStorage;

$encoded = <<<'JSON'
{
    "url": "https://localheinz.com",
    "name": "Andreas Möller",
    "open-source-projects": {
        "ergebnis/data-provider": {
            "downloads": {
                "total": 2,
                "monthly": 1
            }
        },
        "ergebnis/composer-normalize": {
            "downloads": {
                "total": 5,
                "monthly": 2
            }
        }
    }
}
JSON;

$json = Json::fromString($encoded);

$normalizer = new Normalizer\SchemaNormalizer(
    'file:///schema/example.json',
    new SchemaStorage(),
    new SchemaValidator\SchemaValidator(),
    Pointer\Specification::never()
);

$normalized = $normalizer->normalize($json);

标准化后的版本现在将根据JSON模式(在此简单示例中,属性将按模式中的顺序排序,并且附加属性将按名称排序)进行结构化。内部,SchemaNormalizer 使用 justinrainbow/json-schema 来解析模式,并在标准化前后确保JSON文档是有效的。

如果您有不想重新排序的属性,可以使用Pointer\Specification来指定哪些属性不应重新排序。

<?php

declare(strict_types=1);

use Ergebnis\Json\Normalizer;
use Ergebnis\Json\Pointer;
use Ergebnis\Json\SchemaValidator;
use JsonSchema\SchemaStorage;

$encoded = <<<'JSON'
{
    "url": "https://localheinz.com",
    "name": "Andreas Möller",
    "open-source-projects": {
        "ergebnis/data-provider": {
            "downloads": {
                "total": 2,
                "monthly": 1
            }
        },
        "ergebnis/composer-normalize": {
            "downloads": {
                "total": 5,
                "monthly": 2
            }
        }
    }
}
JSON;

$json = Json::fromString($encoded);

$normalizer = new Normalizer\SchemaNormalizer(
    'file:///schema/example.json',
    new SchemaStorage(),
    new SchemaValidator\SchemaValidator(),
    Pointer\Specification::equals(Pointer\JsonPointer::fromJsonString('/open-source-projects'))
);

$normalized = $normalizer->normalize($json);

💡 如需了解更多关于JSON模式的信息,请访问 json-schema.org

WithFinalNewLineNormalizer

当您想确保JSON文件只有一个最后的换行符时,可以使用WithFinalNewLineNormalizer

<?php

declare(strict_types=1);

use Ergebnis\Json\Normalizer;

$encoded = <<<'JSON'
{
    "name": "Andreas Möller",
    "url": "https://localheinz.com"
}


JSON;

$json = Json::fromString($encoded);

$normalizer = new Normalizer\WithFinalNewLineNormalizer();

$normalized = $normalizer->normalize($json);

标准化后的版本现在将只有一个最后的换行符。

WithoutFinalNewLineNormalizer

当您想确保JSON文件没有最后的换行符时,可以使用WithoutFinalNewLineNormalizer

<?php

declare(strict_types=1);

use Ergebnis\Json\Normalizer;

$encoded = <<<'JSON'
{
    "name": "Andreas Möller",
    "url": "https://localheinz.com"
}


JSON;

$json = Json::fromString($encoded);

$normalizer = new Normalizer\WithoutFinalNewLineNormalizer();

$normalized = $normalizer->normalize($json);

标准化后的版本现在将不会有最后的换行符或任何尾随空格。

供应商特定的标准化器

该项目包含以下供应商特定的标准化器

Vendor\Composer\ComposerJsonNormalizer

Vendor\Composer\ComposerJsonNormalizer可用于根据其底层JSON模式标准化composer.json文件。

它组合以下标准化器

Vendor\Composer\BinNormalizer

composer.jsonbin部分包含脚本数组时,Vendor\Composer\BinNormalizer将按值升序对bin部分的元素进行排序。

Vendor\Composer\ConfigHashNormalizer

composer.jsonconfig部分包含配置时,Vendor\Composer\ConfigHashNormalizer将按键升序对这些部分的内容进行排序。

allow-pluginspreferred-install配置选项支持带有通配符的键,并需要特殊处理。

当这些键不使用通配符时,则这些键按升序排序。当这些键使用通配符时,这些键在包名称的末尾排序。由于composer内部通配符功能的实现细节,在中间带有通配符的键的排序是不可行的。

Vendor\Composer\PackageHashNormalizer

composer.json

部分包含任何配置时,Vendor\Composer\PackageHashNormalizer将排序这些部分中的包。

💡 这将使用--sort-packagessort-packages配置标志在requirerequire-dev中使用的行为转移到其他部分。

Vendor\Composer\RepositoriesHashNormalizer

composer.json

部分,Vendor\Composer\RepositoriesHashNormalizer将按excludeonly属性对列出的存储库进行排序。

Vendor\Composer\VersionConstraintNormalizer

composer.json

部分包含版本约束时,Vendor\Composer\VersionConstraintNormalizer将确保

  • 所有版本约束都被修剪

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
    -    "php": " ^8.2 "
    +    "php": "^8.2"
     }
  • 由空格( )或逗号(,)分隔的版本约束(作为逻辑与)现在由空格( )分隔

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
    -    "foo/bar": "1.2.3,2.3.4",
    -    "foo/baz": "2.3.4   3.4.5"
    +    "foo/bar": "1.2.3 2.3.4",
    +    "foo/baz": "2.3.4 3.4.5"
     }
  • 由单个(|)或双管道(||)和任何数量在前后空格分隔的版本约束(作为逻辑或)现在由带有单个前后空格的双管道(||)分隔

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
    -    "php": "^8.1|^8.2",
    -    "foo/bar": "^1.2.3  ||  ^2.3.4"
    +    "php": "^8.1 || ^8.2",
    +    "foo/bar": "^1.2.3 || ^2.3.4"
     }
  • 由短横线(-)分隔的连字符版本范围,前后可以有任意数量的空格,用短横线(-)与单个空格分隔

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#hyphenated-version-range-",
       "require": {
    -    "foo/bar": "1.2.3  -  2.3.4"
    +    "foo/bar": "1.2.3 - 2.3.4"
     }
  • 重复的约束被移除

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
    -    "foo/bar": "^1.0 || ^1.0 || ^2.0"
    +    "foo/bar": "^1.0 || ^2.0"
     }
  • 重叠的约束被移除

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
    -    "foo/bar": "^1.0 || ^1.1 || ^2.0 || ~2.1.0 || 2.4.5"
    +    "foo/bar": "^1.0 || ^2.0"
     }
  • 优先使用波浪线版本范围(~,而不是通配符(*)版本范围

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
         "foo/bar": "*",
    -    "foo/baz": "1.0.*"
    +    "foo/baz": "~1.0.0"
     }
  • 优先使用插入符号版本范围(^,而不是波浪线版本范围(~

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
    -    "foo/bar": "~1",
    -    "foo/baz": "~1.3"
    +    "foo/bar": "^1.0",
    +    "foo/baz": "^1.3"
     }
  • 版本号按升序排序

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/versions.md#version-range",
       "require": {
    -    "foo/bar": "^2.0 || ^1.4"
    +    "foo/bar": "^1.4 || ^2.0"
     }
  • 内联别名中的额外空格被移除

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/aliases.md#require-inline-alias",
       "require": {
    -    "foo/bar": "dev-2.x  as  2.0"
    +    "foo/bar": "dev-2.x as 2.0"
     }
  • 移除无用的内联别名

     {
       "homepage": "https://getcomposer.org.cn/doc/articles/aliases.md#require-inline-alias",
       "require": {
    -    "foo/bar": "2.0 as 2.0"
    +    "foo/bar": "2.0"
     }
  • 移除版本约束中的前导v前缀

     {
       "require": {
    -    "foo/bar": "^v1.2",
    -    "foo/baz": "v1.3.7"
    +    "foo/bar": "^1.2",
    +    "foo/baz": "1.3.7"
     }
  • xX用于通配符替换为*

     {
       "require": {
    -    "foo/bar": "1.x",
    -    "foo/baz": "2.3.X",
    -    "foo/qux": "x"
    +    "foo/bar": "^1.0",
    +    "foo/baz": "~2.3.0",
    +    "foo/qux": "*"
     }

变更日志

本项目维护者记录项目的重要变更到变更日志中。

贡献

本项目维护者建议遵循贡献指南

行为准则

本项目维护者要求贡献者遵循行为准则

一般支持政策

本项目提供有限的支持。

您可以通过赞助 @localheinz请求与本项目相关的服务发票来支持本项目的维护。

PHP版本支持政策

本项目支持具有活跃和安全支持的PHP版本。

本项目维护者在PHP版本首次发布后添加对该版本的支持,并在其达到安全支持结束阶段时停止对该版本的支持。

安全策略

本项目有一个安全政策

许可证

本项目使用MIT许可证

鸣谢

Vendor\Composer\PackageHashNormalizer中排序软件包的算法是从Composer\Json\JsonManipulator::sortPackages()(最初由Nils AdermannJordi Boggiano许可MIT)中采用的,我最初在composer/composer#3549composer/composer#3872中向composer/composer贡献了该算法。

社交

关注Twitter上的@localheinz和@ergebnis。