kynx / code-utils
生成 PHP 代码的实用工具
Requires
- php: ~8.1 || ~8.2
- ext-intl: *
Requires (Dev)
- laminas/laminas-coding-standard: ^2.4
- phpunit/phpunit: ^9.5
- vimeo/psalm: ^4.27
README
生成 PHP 代码的实用工具。
规范化工具
规范化工具可以将有效的 UTF-8 字符串生成可读的 PHP 标签(类名、命名空间、属性名等),转写为 ASCII,并拼写任何无效字符。
用法
以下代码(请原谅日语——某种翻译工具告诉我它的意思是“宠物店”)
<?php use Kynx\Code\Normalizer\ClassNameNormalizer; $normalizer = new ClassNameNormalizer('Controller'); $namespace = $normalizer->normalize('ペット \ ショップ'); echo $namespace;
输出
Petto\Shoppu
和
<?php use Kynx\Code\Normalizer\PropertyNameNormalizer; $normalizer = new PropertyNameNormalizer(); $property = $normalizer->normalize('2 $ bill'); echo $property;
输出
twoDollarBill
查看更多示例的测试。
为什么?
永远不要运行来自不受信任用户输入生成的代码。但是,有一些情况下,你确实希望输出(主要是)受信任输入生成的代码。
在我的情况下,我需要从 OpenAPI 规范生成类和属性。对现有字符没有严格的规定,只有一条模糊的“建议遵循常见的编程命名约定”。不管怎样。
如何?
每个规范化工具使用 ext-intl
的 Transliterator 将 UTF-8 字符串转换为拉丁-ASCII。如果一个字符在 ASCII 中没有等效字符(“€”符号是一个很好的例子),它就使用字符的 Unicode 名称 来拼写(在经过一些轻微的清理后变成 Euro
)。对于不在 PHP 标签中有效的 ASCII 字符,它提供自己的拼写。例如,反引号 "`" 变成 Backtick
。
初始数字也被拼写出来:“123foo”变成 OneTwoThreeFoo
。最后,将保留词后缀添加到用户提供的字符串中,以免混乱。在上面的第一个用法示例中,如果我们规范化“class”,它将变成 ClassController
。
结果可能不会很漂亮。如果由于某种疯狂的原因你的输入包含 ͖
- 把你的眼镜戴上! - 标签将包含 CombiningRightArrowheadAndUpArrowheadBelow
。但它 确实是 有效的 PHP,并且有可能是与原始代码一样独特。这让我想到了...
唯一标签生成器
规范化过程将大约一百万个 Unicode 代码点减少到只有 162 个 ASCII 字符。然后通过删除分隔符、减少空白并将它转换成 camelCase、snake_case 或任何你喜欢的编程风格来进一步破坏标签。它会损失一些信息——我们对此无能为力。
唯一标签生成器的任务是使用 UniqueStrategyInterface
为它给出的列表中任何非唯一的类名添加回丢失的唯一性。
要保证类名标签集合内的唯一性,请使用 UniqueClassLabeller
<?php use Kynx\Code\Normalizer\ClassNameNormalizer; use Kynx\Code\Normalizer\UniqueClassLabeler; use Kynx\Code\Normalizer\UniqueStrategy\NumberSuffix; $labeler = new UniqueClassLabeler(new ClassNameNormalizer('Handler'), new NumberSuffix()); $labels = ['Déjà vu', 'foo', 'deja vu']; $unique = $labeler->getUnique($labels); var_dump($unique);
输出
array(3) {
'Déjà vu' =>
string(7) "DejaVu1"
'foo' =>
string(3) "Foo"
'deja vu' =>
string(7) "DejaVu2"
}
为每个规范化工具都有标签生成器: UniqueClassLabeler
、UniqueConstantLabeler
、UniquePropertyLabeler
和 UniqueVariableLabeler
。此外,我们还提供了 NumberSuffix
的 UniqueStrategyInterface
实现,并提供了 SpellOutOrdinalPrefix
策略。使用该策略而不是上面的 NumberSuffix
会输出
array(3) {
'Déjà vu' =>
string(11) "FirstDejaVu"
'foo' =>
string(3) "Foo"
'deja vu' =>
string(12) "SecondDejaVu"
}
有点可爱,但对我来说有点啰嗦。