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 =数组();}/ /……}

就是这样!你现在有了所需的所有工具和知识容易过程选项在您的代码中。

这项工作,包括代码示例,许可下Creative Commons冲锋队3.0许可证。