OptionsResolver组件
编辑该页面警告:你浏览的文档欧宝官网下载appob娱乐下载Symfony 2.7,不再维护。
读这个页面的更新版本Symfob娱乐下载ony 6.2(当前的稳定版本)。
OptionsResolver组件
OptionsResolver组件是array_replace类固醇。它允许您创建一个选项系统所需的选项,默认值,验证(类型、价值)、标准化和更多。
安装
1
美元作曲家需要symfony / opob娱乐下载tions-resolver
或者,您可以克隆的https://github.com/ob娱乐下载symfony/options-resolver存储库。
请注意
如果你安装这个组件之外的Symfony应用程序,你必须要求ob娱乐下载供应商/ autoload.php
文件在你的代码,使作曲家提供的类加载机制。读这篇文章为更多的细节。
在之前的版本
2.6
这个文档是欧宝官网下载appSymfony 2.6之后写的。ob娱乐下载如果你使用一个旧版本,请阅读Symfonyob娱乐下载 2.5文档欧宝官网下载app。变化的列表,请参阅更新日志。
使用
想象你有一个梅勒
类有四个选项:主机
,用户名
,密码
和港口
:
1 2 3 4 5 6 7 8 9
类梅勒{受保护的美元选项;公共函数__construct(数组美元选项=数组()){美元这- >选择=美元选项;}}
当访问选择美元
,您需要添加许多样板代码检查哪些选项设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24日25日26日
类梅勒{/ /……公共函数sendMail(美元从,美元来){美元邮件=……;美元邮件- >setHost (收取(美元这- >选项(“主机”])?美元这- >选项(“主机”]:“smtp.example.org”);美元邮件- >setUsername (收取(美元这- >选项(“用户名”])?美元这- >选项(“用户名”]:“用户”);美元邮件- >向setPassword (收取(美元这- >选项(“密码”])?美元这- >选项(“密码”]:“爸爸$ $词”);美元邮件- >setPort (收取(美元这- >选项(“端口”])?美元这- >选项(“端口”]:25);/ /……}}
这个样板是难以阅读和重复。选项的默认值也埋在代码的业务逻辑。使用array_replace修复:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
类梅勒{/ /……公共函数__construct(数组美元选项=数组()){美元这- >选择= array_replace (数组(“主机”= >“smtp.example.org”,“用户名”= >“用户”,“密码”= >“爸爸$ $词”,“端口”= >25),美元选项);}}
现在所有的四个选项都是保证集。但如果用户的梅勒
类是一个错误吗?
1 2 3
美元梅勒=新梅勒(数组(“usernme”= >“johndoe”,/ / usernme拼写错误(而不是用户名)));
没有显示错误信息。在最好的情况下,错误在测试过程中会出现,但开发者会花时间找问题。在最坏的情况下,不可能出现错误直到部署到活动的系统。
幸运的是,OptionsResolver类可以帮助您解决这个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
使用ob娱乐下载\组件\OptionsResolver\OptionsResolver;类梅勒{/ /……公共函数__construct(数组美元选项=数组()){美元解析器=新OptionsResolver ();美元解析器- >setDefaults (数组(“主机”= >“smtp.example.org”,“用户名”= >“用户”,“密码”= >“爸爸$ $词”,“端口”= >25));美元这- >选择=美元解析器- >解决(美元选项);}}
像以前一样,所有选项都将保证集。此外,一个UndefinedOptionsException如果抛出一个未知的选择是通过:
1 2 3 4 5 6
美元梅勒=新梅勒(数组(“usernme”= >“johndoe”));/ / UndefinedOptionsException:选择“usernme”并不存在。/ /选项:“主机”、“密码”、“港”、“用户名”
剩下的代码可以访问选项的值没有样板代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/ /……类梅勒{/ /……公共函数sendMail(美元从,美元来){美元邮件=……;美元邮件- >setHost (美元这- >选项(“主机”]);美元邮件- >setUsername (美元这- >选项(“用户名”]);美元邮件- >向setPassword (美元这- >选项(“密码”]);美元邮件- >setPort (美元这- >选项(“端口”]);/ /……}}
这是一个很好的实践将选择配置到一个单独的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24
/ /……类梅勒{/ /……公共函数__construct(数组美元选项=数组()){美元解析器=新OptionsResolver ();美元这- >configureOptions (美元解析器);美元这- >选择=美元解析器- >解决(美元选项);}公共函数configureOptions(OptionsResolver美元解析器){美元解析器- >setDefaults (数组(“主机”= >“smtp.example.org”,“用户名”= >“用户”,“密码”= >“爸爸$ $词”,“端口”= >25,“加密”= >零));}}
首先,代码变得易于阅读,特别是如果构造函数不仅处理选项。第二,子类会覆盖configureOptions ()
调整方法的配置选项:
1 2 3 4 5 6 7 8 9 10 11 12 13
/ /……类GoogleMailer扩展梅勒{公共函数configureOptions(OptionsResolver美元解析器){父::configureOptions (美元解析器);美元解析器- >setDefaults (数组(“主机”= >“smtp.google.com”,“加密”= >“ssl”));}}
需要选择
如果调用者必须设置一个选项,该选项传递给setRequired ()。例如,使主机
选择需要,你能做什么:
1 2 3 4 5 6 7 8 9 10 11
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setRequired (“主机”);}}
2.6
Symfonob娱乐下载y的2.6,setRequired ()
接受两个数组或一个选项的选项。在2.6之前,你只能通过数组。
如果您省略一个必需的选项,一个MissingOptionsException将被扔:
1 2 3
美元梅勒=新梅勒();/ / MissingOptionsException:所需的选项“主机”不见了。
的setRequired ()方法接受一个名称或一组选项名称,如果你有不止一个需要选择:
1 2 3 4 5 6 7 8 9 10 11
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setRequired (数组(“主机”,“用户名”,“密码”));}}
2.6
的方法isRequired ()和getRequiredOptions ()在Symfony 2.6中引入的。ob娱乐下载
使用isRequired ()发现如果一个选项是必需的。您可以使用getRequiredOptions ()来检索所需的所有选项的名称:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/ /……类GoogleMailer扩展梅勒{公共函数configureOptions(OptionsResolver美元解析器){父::configureOptions (美元解析器);如果(美元解析器- >isRequired (“主机”)){/ /……}美元requiredOptions=美元解析器- >getRequiredOptions ();}}
2.6
的方法isMissing ()和getMissingOptions ()在Symfony 2.6中引入的。ob娱乐下载
如果你想要检查是否需要选择是失踪从默认选项,您可以使用isMissing ()。这之间的区别isRequired ()是,这个方法将返回false如果需要选择已经设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31 32 33 34
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setRequired (“主机”);}}/ /……类GoogleMailer扩展梅勒{公共函数configureOptions(OptionsResolver美元解析器){父::configureOptions (美元解析器);美元解析器- >isRequired (“主机”);/ / = >正确的美元解析器- >isMissing (“主机”);/ / = >正确的美元解析器- >setDefault (“主机”,“smtp.google.com”);美元解析器- >isRequired (“主机”);/ / = >正确的美元解析器- >isMissing (“主机”);/ / = >假}}
该方法getMissingOptions ()允许您访问所有失踪的名称选项。
类型验证
选项您可以运行额外的检查,以确保他们正确传递。验证的类型选择,电话setAllowedTypes ():
1 2 3 4 5 6 7 8 9 10 11 12
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setAllowedTypes (“主机”,“字符串”);美元解析器- >setAllowedTypes (“端口”,数组(“零”,“int”));}}
对于每个选项,您可以定义一个类型或可接受的类型的数组。你可以传递任何类型的一个is_ <类型> ()
PHP函数中定义。此外,您可以通过完全限定的类或接口的名称。
如果你现在通过一个无效的选项,一个InvalidOptionsException抛出:
1 2 3 4 5 6
美元梅勒=新梅勒(数组(“主机”= >25));/ / InvalidOptionsException:选择“主机”与“25”是价值/ /将类型的“字符串”
在子类中,您可以使用addAllowedTypes ()添加额外的允许没有删除已经设置的类型。
2.6
在Symfonob娱乐下载y 2.6之前,setAllowedTypes ()
和addAllowedTypes ()
预期得到的值作为一个数组映射选项允许类型名称:解析器- > setAllowedTypes美元(阵列(“端口”= >数组(“空”、“int”)));
值验证
一些选项只能取一个固定的预定义的值列表。例如,假设梅勒
类都有一个运输
选项之一sendmail
,邮件
和smtp
。使用这种方法setAllowedValues ()验证通过选择包含这些值之一:
1 2 3 4 5 6 7 8 9 10 11 12
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setDefault (“交通”,“发送邮件”);美元解析器- >setAllowedValues (“交通”,数组(“发送邮件”,“邮件”,“smtp”));}}
如果你通过一个无效的交通,一个InvalidOptionsException抛出:
1 2 3 4 5 6
美元梅勒=新梅勒(数组(“交通”= >“发送邮件”));/ / InvalidOptionsException:选择“运输”的值/ /“发送邮件”,但预计将“发送邮件”,“邮件”,“smtp”
对更复杂的验证方案,选择通过关闭它返回真正的
可接受的值和假
无效值:
1 2 3 4
/ /……美元解析器- >setAllowedValues (“交通”,函数(美元价值){/ /返回true或false});
在子类中,您可以使用addAllowedValues ()添加额外的允许没有删除已经设置的值。
2.6
在Symfonob娱乐下载y 2.6之前,setAllowedValues ()
和addAllowedValues ()
预期得到的值作为数组映射选项名称允许的值:解析器- > setAllowedValues美元(阵列(“运输”= >数组(“发送邮件”,“邮件”,“smtp”)));
选择归一化
有时,选项值需要归一化之前,您可以使用它们。例如,假设主机
应该开始http://
。要做到这一点,您可以编写标准化者。标准化者执行验证后一个选项。您可以配置一个标准化者通过调用setNormalizer ():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
使用ob娱乐下载\组件\OptionsResolver\选项;/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setNormalizer (“主机”,函数(选项美元选项,美元价值){如果(“http://”! = = substr (美元价值,0,7)){美元价值=“http://”。美元价值;}返回美元价值;});}}
2.6
该方法setNormalizer ()是在Symfony 2.6中引入的。ob娱乐下载之前,你必须使用setNormalizers ()。
标准化者接收到实际美元的价值
并返回标准化形式。你也看到,关闭以一个选择美元
参数。这是有用的,如果你需要使用其他选项在归一化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setNormalizer (“主机”,函数(选项美元选项,美元价值){如果(“http://”! = = substr (美元价值,0,7)& &“https://”! = = substr (美元价值,0,8)){如果(“ssl”= = =美元选项(“加密”){美元价值=“https://”。美元价值;}其他的{美元价值=“http://”。美元价值;}}返回美元价值;});}}
依赖于另一个选项的默认值
假设你想设置的默认值港口
选择基于加密的用户选择梅勒
类。更准确地说,你想设置端口465年
如果使用SSL和25
否则。
您可以实现此功能通过一个闭包的默认值港口
选择。关闭接收选项作为参数。根据这些选项,您可以返回所需的默认值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
使用ob娱乐下载\组件\OptionsResolver\选项;/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setDefault (“加密”,零);美元解析器- >setDefault (“端口”,函数(选项美元选项){如果(“ssl”= = =美元选项(“加密”){返回465年;}返回25;});}}
谨慎
可调用的参数必须类型暗示选项
。否则,可调用本身被认为是选项的默认值。
请注意
关闭只是如果执行港口
选择不设置由用户或覆盖在一个子类。
之前设置的默认值可以通过添加访问关闭第二个参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setDefaults (数组(“加密”= >零,“主机”= >“example.org”));}}类GoogleMailer扩展梅勒{公共函数configureOptions(OptionsResolver美元解析器){父::configureOptions (美元解析器);美元解析器- >setDefault (“主机”,函数(选项美元选项,美元previousValue){如果(“ssl”= = =美元选项(“加密”){返回“secure.example.org”}/ /基类的默认值配置返回美元previousValue;});}}
示例中可以看到,此功能主要是有用的,如果你想重复使用默认值设置在子类的父类。
选项没有默认值
在某些情况下,它是有用的定义一个选项没有设置一个默认值。这是有用的,如果你需要知道是否用户实际上设置一个选项。例如,如果您设置一个选项的默认值,这是不可能的知道用户通过这个值或如果它只是来自默认:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setDefault (“端口”,25);}/ /……公共函数sendMail(美元从,美元来){/ /这是默认值或类的调用者真的/ /设置端口25 ?如果(25= = =美元这- >选项(“端口”){/ /……}}}
2.6
该方法setDefined ()是在Symfony 2.6中引入的。ob娱乐下载之前,你必须使用setOptional ()。
您可以使用setDefined ()定义一个选项没有设置一个默认值。然后选择只会包含在选项如果它实际上是传递给解决解决():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17日18 19 20 21日22日23日24日25日26日27 28 29 30 31
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setDefined (“端口”);}/ /……公共函数sendMail(美元从,美元来){如果(array_key_exists (“端口”,美元这- >选项)){回声“集合!”;}其他的{回声“没有!”;}}}美元梅勒=新梅勒();美元梅勒- >sendMail (美元从,美元来);/ / = >没有设置!美元梅勒=新梅勒(数组(“端口”= >25));美元梅勒- >sendMail (美元从,美元来);/ / = >设置!
你也可以通过选项数组的名字,如果你想定义多个选择的:
1 2 3 4 5 6 7 8 9 10
/ /……类梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){/ /……美元解析器- >setDefined (数组(“端口”,“加密”));}}
2.6
该方法isDefined ()和getDefinedOptions ()在Symfony 2.6中引入的。ob娱乐下载
的方法isDefined ()和getDefinedOptions ()让你找出哪些选项定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/ /……类GoogleMailer扩展梅勒{/ /……公共函数configureOptions(OptionsResolver美元解析器){父::configureOptions (美元解析器);如果(美元解析器- >isDefined (“主机”)){/ /以下被称为之一:/ /解析器- > setDefault(“主机”,…);/ /解析器- > setRequired('主机');/ /解析器- > setDefined('主机');}美元definedOptions=美元解析器- >getDefinedOptions ();}}
性能调整
与当前的实现configureOptions ()
方法将呼吁每一个的实例梅勒
类。根据选择的数量配置和创建实例的数量,这可能为应用程序添加显著的开销。如果开销成为一个问题,你可以改变你的每个类只配置一次代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24日25日26日
/ /……类梅勒{私人静态美元resolversByClass=数组();受保护的美元选项;公共函数__construct(数组美元选项=数组()){/ /这是什么类型的梅勒,梅勒,GoogleMailer,…吗?美元类= get_class (美元这);/ /是configureOptions()之前执行这个类?如果(!收取(自我::$resolversByClass [美元类))){自我::$resolversByClass [美元类]=新OptionsResolver ();美元这- >configureOptions (自我::$resolversByClass [美元类]);}美元这- >选择=自我::$resolversByClass [美元类]- >解决(美元选项);}公共函数configureOptions(OptionsResolver美元解析器){/ /……}}
现在,OptionsResolver每次创建类实例和重用的。请注意,这可能会导致长时间运行的应用程序中的内存泄漏,如果默认选项包含对象的引用或对象图。如果是这种情况,实现方法clearOptionsConfig ()
并定期称之为:
1 2 3 4 5 6 7 8 9 10 11 12
/ /……类梅勒{私人静态美元resolversByClass=数组();公共静态函数clearOptionsConfig(){自我::$resolversByClass =数组();}/ /……}
就是这样!你现在有了所需的所有工具和知识容易过程选项在您的代码中。