ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ShowDoc 内置 Doctrine Inflector 实战指南:PHP 单词复数化、单复数转换与命名风格变形完全解析

ShowDoc 内置 Doctrine Inflector 实战指南:PHP 单词复数化、单复数转换与命名风格变形完全解析 ShowDoc 内置 Doctrine Inflector 实战指南PHP 单词复数化、单复数转换与命名风格变形完全解析【免费下载链接】showdocShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具项目地址: https://gitcode.com/gh_mirrors/sh/showdoc导读Doctrine Inflector 是 Doctrine 生态中一个轻量级的 PHP 字符串变形库核心能力包括单词的复数化pluralize、单数化singularize、camelCase 与下划线命名风格互转、单词首字母大写capitalize、URL 友好化urlize与去重音符号unaccent等。本仓库 ShowDoc 的服务器端server/目录通过 Composer 引入了该库doctrine/inflector2.1.0作为illuminate/support的依赖因此它实际已成为 ShowDoc 后端技术栈的一部分。本文将基于仓库内 官方使用文档 的完整脉络结合 源码实现为你系统讲解 Inflector 的安装、工厂创建、多语言支持、自定义规则以及全部核心方法的用法与底层原理。一、Doctrine Inflector 是什么官方文档在 docs/en/index.rst 的开篇即给出定义Inflector 提供用于文本变形的各种方法核心功能包括复数化pluralization单数化singularizationcamelCase 与under_score下划线风格互转单词首字母大写capitalizing words其包描述见 composer.json也印证了定位a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words一个可对单词进行大小写、单复数形式字符串操作的小型库。它不依赖任何第三方运行库仅要求php: ^7.2 || ^8.0并遵循 MIT 许可证。二、安装方式官方文档给出的安装方式是通过 Composer$ composer require doctrine/inflector在本仓库中该依赖已被锁定为2.1.0版本详见根目录 composer.lock约第 207–279 行其依赖关系是illuminate/supportLaravel 组件声明doctrine/inflector: ^1.4|^2.0也就是说 ShowDoc 通过 Laravel 组件间接引入了 Inflector。如果你需要查看已 vendor 到本仓库的源码可直接浏览 server/vendor/doctrine/inflector/src 目录。三、基本用法通过工厂创建 Inflector官方文档指出使用 Inflector 非常简单通过Doctrine\Inflector\InflectorFactory类即可创建Doctrine\Inflector\Inflector实例use Doctrine\Inflector\InflectorFactory; $inflector InflectorFactory::create()-build();默认创建的是**英语English**Inflector。如需使用其他语言将语言常量传给createForLanguage()方法use Doctrine\Inflector\InflectorFactory; use Doctrine\Inflector\Language; $inflector InflectorFactory::createForLanguage(Language::SPANISH)-build();从源码 InflectorFactory.php 可以看到create()本质就是createForLanguage(Language::ENGLISH)的别名而createForLanguage()内部是一个switch分发到对应语言专属的InflectorFactory如果传入不支持的字符串会抛出InvalidArgumentExceptiondefault: throw new InvalidArgumentException(sprintf( Language %s is not supported., $language ));注意Language::*常量的实际取值见 Language.php并非枚举对象而是普通字符串常量例如Language::ENGLISH english、Language::NORWEGIAN_BOKMAL norwegian-bokmal因此createForLanguage()的参数类型是string。四、支持的语言官方文档列出的受支持语言如下常量均定义在Doctrine\Inflector\Language语言常量对应语言源码目录src/Rules/下Language::ENGLISH英语English/Language::ESPERANTO世界语Esperanto/Language::FRENCH法语French/Language::NORWEGIAN_BOKMAL挪威语博克马尔文NorwegianBokmal/Language::PORTUGUESE葡萄牙语Portuguese/Language::SPANISH西班牙语Spanish/Language::TURKISH土耳其语Turkish/需要说明的是实际仓库源码中还存在一个额外的Italian意大利语规则目录Rules/Italian不过它尚未被注册进InflectorFactory的switch分发中——从源码结构看这可能是为后续版本预留的语言支持官方文档未将其列入。每种语言的规则目录都统一包含四个文件Inflectible.php正则变换与不规则词表、Uninflected.php不可变形词表、Rules.php组装规则集、InflectorFactory.php语言专属工厂。五、手动构造 Inflector如果不希望使用工厂也可以手动组装 Inflector。官方文档给出的构造示例use Doctrine\Inflector\CachedWordInflector; use Doctrine\Inflector\RulesetInflector; use Doctrine\Inflector\Rules\English; $inflector new Inflector( new CachedWordInflector(new RulesetInflector( English\Rules::getSingularRuleset() )), new CachedWordInflector(new RulesetInflector( English\Rules::getPluralRuleset() )) );这里涉及 Inflector 的核心设计——装饰器链对应三个类Inflector.php构造函数接收两个WordInflector分别用于单数化singularizer与复数化pluralizer。pluralize()与singularize()方法内部只是简单地把任务委托给这两个组件见源码第 491–506 行。RulesetInflector.php真正的规则引擎。它对一组Ruleset依次执行三条匹配规则若单词命中uninflected不可变形模式原样返回若命中不规则词表irregular/substitutions且结果与输入不同返回该结果若命中正则变换regular/transformations且结果与输入不同返回该结果全部未命中则保持原样。CachedWordInflector.php带内存缓存的装饰器用$this-cache[$word] ?? $this-cache[$word] ...记住每个词的变形结果避免对高频词反复执行正则匹配。工厂的build()方法见 GenericLanguageInflectorFactory.php正是把「语言默认规则集 用户自定义规则集」统一组装成上述装饰器链。规则集内部结构每个语言的Rules.php会构建一个Ruleset它由三部分组成见 Ruleset.phpRegular正则变换Transformations集合按顺序执行正则替换第一个命中的变换生效见 Transformations.php。每个Transformation由Pattern与替换字符串构成最终通过preg_replace完成替换见 Transformation.php。Uninflected不可变形Patterns集合会被合并为一个/^(?:...)$/i的整体正则做整词匹配见 Patterns.php命中即不做变形。Irregular不规则词Substitutions集合基于大小写不敏感的映射表做精确整词替换并自动保留首字母大小写见 Substitutions.php。Pattern的构造有个细节如果模式字符串以/开头则直接作为完整正则使用否则会自动包装为/模式/i大小写不敏感见 Pattern.php。英语规则示例英语规则定义在 Rules/English/Inflectible.php 与 Rules/English/Uninflected.php。以单数化规则为例典型条目包括yield new Transformation(new Pattern((x|ch|ss|sh)es$), \1); // boxes - box yield new Transformation(new Pattern(([^aeiouy]|qu)ies$), \1y); // babies - baby yield new Transformation(new Pattern(s$), ); // browsers - browser而 Rules/English/Rules.php 负责组装单数规则集使用「翻转后的不规则词表」getFlippedSubstitutions()即把复数形式映射回单数形式复数规则集则直接使用原始不规则词表。六、添加新语言支持官方文档说明若想为 Inflector 增加新语言支持可以参考Doctrine\Inflector\Rules命名空间下已有语言的实现以及Doctrine\Tests\Inflector\Rules下的测试用例复制其中一个语言目录并按目标语言更新规则即可。从仓库源码看一种新语言需要提供四部分Inflectible.php——用yield生成器给出复数化与单数化的Transformation列表以及不规则词Substitution列表Uninflected.php——给出不可变形词Pattern列表Rules.php——实现getSingularRuleset()与getPluralRuleset()InflectorFactory.php——继承GenericLanguageInflectorFactory实现抽象方法返回上述两个规则集同时在InflectorFactory::createForLanguage()的switch中注册对应分支。完成开发后按官方文档指引向doctrine/inflector仓库提交 Pull Request 即可。七、自定义规则工厂级定制官方文档提供了一套完整的自定义规则示例演示如何通过withSingularRules()与withPluralRules()为工厂追加自定义的单复数规则use Doctrine\Inflector\InflectorFactory; use Doctrine\Inflector\Rules\Pattern; use Doctrine\Inflector\Rules\Patterns; use Doctrine\Inflector\Rules\Ruleset; use Doctrine\Inflector\Rules\Substitution; use Doctrine\Inflector\Rules\Substitutions; use Doctrine\Inflector\Rules\Transformation; use Doctrine\Inflector\Rules\Transformations; use Doctrine\Inflector\Rules\Word; $inflector InflectorFactory::create() -withSingularRules( new Ruleset( new Transformations( new Transformation(new Pattern(/^(bil)er$/i), \1), new Transformation(new Pattern(/^(inflec|contribu)tors$/i), \1ta) ), new Patterns(new Pattern(singulars)), new Substitutions(new Substitution(new Word(spins), new Word(spinor))) ) ) -withPluralRules( new Ruleset( new Transformations( new Transformation(new Pattern(^(bil)er$), \1), new Transformation(new Pattern(^(inflec|contribu)tors$), \1ta) ), new Patterns(new Pattern(noflect), new Pattern(abtuse)), new Substitutions( new Substitution(new Word(amaze), new Word(amazable)), new Substitution(new Word(phone), new Word(phonezes)) ) ) ) -build();这段代码展示了自定义规则集的完整组成语法其中每个Ruleset由三个参数构成参数类作用第一个Transformations一组按顺序匹配的正则变换Transformation第二个Patterns一组命中后不做变形的整词模式Pattern第三个Substitutions一组不规则整词替换Substitution从Word到Wordreset 参数替换还是追加withSingularRules()/withPluralRules()还接受第二个布尔参数reset默认false。从 GenericLanguageInflectorFactory.php 的实现看reset false默认自定义规则集通过array_unshift插入到规则列表最前即优先于语言默认规则执行reset true先清空已有规则列表再用自定义规则集替换即完全抛弃该语言的默认规则。工厂的build()最终会把singularRulesets/pluralRulesets展开为多个RulesetInflector参数外层再套上CachedWordInflector完成缓存。八、空操作No-opInflectorNull Object 模式官方文档介绍Doctrine\Inflector\NoopWordInflector可用于配置一个对复数化/单数化不做任何操作的 Inflector输入是什么输出就是什么这是 Null Object 设计模式 的一个实现。use Doctrine\Inflector\Inflector; use Doctrine\Inflector\NoopWordInflector; $inflector new Inflector(new NoopWordInflector(), new NoopWordInflector());对应的实现非常简洁NoopWordInflector.phpclass NoopWordInflector implements WordInflector { public function inflect(string $word): string { return $word; } }其价值在于当业务层需要「可插拔」的变形策略例如某些场景关闭单复数转换时可以无侵入地替换掉真实规则而无需改动调用方代码。九、核心 API 逐一详解以下方法均定义在 Inflector.php 中除pluralize/singularize依赖上述装饰器链外其余多为纯字符串/正则处理。1. tableize类名 → 数据表名将ModelName转换为model_nameecho $inflector-tableize(ModelName); // model_name实现第 232–244 行先用正则~(?\w)([A-Z])~u在每个大写字母前插入下划线再通过mb_strtolower()转小写使用多字节安全函数兼容 UTF-8 字符。2. classify表名/下划线 → 类名将model_name转换为ModelNameecho $inflector-classify(model_name); // ModelName实现第 249–252 行调用ucwords($word, _-)以空格、下划线、连字符为分隔符逐词大写再移除这三种分隔符。因此my-page_name也会变成MyPageName。3. camelize表名 → 驼峰命名camelize 复用 classify 后将首字符转为小写echo $inflector-camelize(model_name); // modelName实现第 257–260 行就是lcfirst($this-classify($word))很适合生成 PHP 方法名或 JavaScript 变量名。4. capitalize可配置分隔符的首字母大写官方文档明确指出该方法行为类似 PHP 内置的ucwords但允许自定义单词分隔符而非只按空白分割$string top-o-the-morning to all_of_you!; echo $inflector-capitalize($string); // Top-O-The-Morning To All_of_you! echo $inflector-capitalize($string, -_ ); // Top-O-The-Morning To All_Of_You!实现第 287–290 行本质就是ucwords($string, $delimiters)第二个参数$delimiters的默认值是 \n\t\r\0\x0B-空白类字符加连字符。注意第一个调用未传入_作为分隔符因此all_of_you中只有all被大写第二个调用显式传入-_ 三个词都被正确大写。5. pluralize / singularize复数化与单数化返回单词的复数 / 单数形式echo $inflector-pluralize(browser); // browsers echo $inflector-singularize(browsers); // browser实现第 491–506 行分别委托给构造时注入的singularizer/pluralizer即上一节描述的三层装饰器链CachedWordInflector → RulesetInflector → 语言规则集。英语规则中如(x|ch|ss|sh)es$ → \1覆盖boxes/boxes类词形s$ → 覆盖常规复数词尾。6. urlize生成 URL 友好字符串从一段文本生成 URL 友好的 slugecho $inflector-urlize(My first blog post); // my-first-blog-post实现第 448–482 行分四步先unaccent()去除重音与非法字符再统一转小写优先mb_strtolower随后依次执行四组正则替换非单词字符 → 空格、连续大写拆分为下划线、字母数字边界的大写拆分、非法字符序列 → 连字符最后用trim($urlized, -)去掉首尾多余的连字符。因此它不仅能处理普通文本也能处理camelCase混合文本的 slug 化。7. unaccent去重音符号去除字符串中的重音字符echo $inflector-unaccent(año); // ano实现第 335–438 行较为精巧若字符串不含高位字节/[\x80-\xff]/不命中则直接返回通过seemsUtf8()第 297–326 行逐字节按 UTF-8 编码特征判断区分 UTF-8 与 ISO-8859-1UTF-8 场景使用strtr()对照ACCENTED_CHARACTERS常量映射表第 26–215 行覆盖数百个拉丁扩展字符如Ä → Ae、ß → ss、Œ → OE逐一替换非 UTF-8 场景则按 ISO-8859-1 的字节码表处理单字节与双字节映射。十、Legacy API1.x 兼容说明官方文档特别提醒Inflector 1.x 时代的 API 仍然可用但将在未来版本中弃用并计划在3.0 版本中移除同时除英语外的多语言支持仅存在于 2.0 新 API 中。因此对于新代码官方建议统一使用本文介绍的 2.x 工厂 APIInflectorFactory::create()/createForLanguage()避免后续升级时遭遇破坏性变更。十一、在本仓库中的实际位置与版本最后把视角拉回本仓库方便读者直接查阅官方文档 server/vendor/doctrine/inflector/docs/en/index.rst本文的骨架来源全部源码 server/vendor/doctrine/inflector/src包信息与 PHP 版本要求 server/vendor/doctrine/inflector/composer.json锁定版本2.1.0与依赖方 根目录 composer.lockdoctrine/inflector作为illuminate/support的依赖被引入版本约束^1.4|^2.0十二、致谢与规则来源按官方文档说明本库的语言规则改编自多个知名开源实现包括 Ruby On Rails 的 ActiveSupport Inflector、ICanBoogie Inflector 以及 CakePHP Inflector。其中英语的复数/单数正则体系、不规则词表等规则设计很大程度上延续了这些前辈项目的成熟方案这也是 Inflector 能在多语言、多框架环境中保持规则一致性的原因。【免费下载链接】showdocShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具项目地址: https://gitcode.com/gh_mirrors/sh/showdoc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表