用 symfony/options-resolver 优雅的校验类初始化选项

示例类

use Symfony\Component\OptionsResolver\OptionsResolver;

class Email
{
    private $options;

    /**
     * Email constructor.
     *
     * @param  array  $options
     */
    public function __construct(array $options = [])
    {
        $this->setOptions($options);
    }

    /**
     * Configuration options.
     *
     * @param \Closure $closure
     * @param null     $object
     *
     * @return array
     */
    protected function configureOptions(array $options, Closure $closure, $object = null)
    {
        $resolver = new OptionsResolver();

        $closure($resolver);

        if ($object instanceof Closure) {
            return $object()->options = $resolver->resolve($options);
        }

        if (is_object($object)) {
            return $object->options = $resolver->resolve($options);
        }

        if (is_string($object) && class_exists($object)) {
            $object = new $object();

            return $object->options = $resolver->resolve($options);
        }

        return $resolver->resolve($options);
    }

    /**
     * @return mixed
     */
    public function getOptions()
    {
        return $this->options;
    }

    /**
     * @param  array  $options
     */
    public function setOptions(array $options): void
    {
        $this->options = $this->configureOptions($options, function (OptionsResolver $resolver) {
            $resolver->setDefaults([
                'host' => 'smtp.example.org',
                'username' => 'user',
                'password' => 'password',
                'port' => 25,
            ]);
            $resolver->setRequired(['host', 'username', 'password', 'port']);
            $resolver->setAllowedTypes('host', 'string');
            $resolver->setAllowedTypes('username', 'string');
            $resolver->setAllowedTypes('password', 'string');
            $resolver->setAllowedTypes('port', 'int');
        });
    }
}

选项通过校验

$email = new Email([
    'host'     => 'smtp.example.org',
    'username' => 'user',
    'password' => 'password',
    'port'     => 25,
]);

var_export($email);
Email::__set_state(array(
    'options' =>
        array (
            'host' => 'smtp.example.org',
            'username' => 'user',
            'password' => 'password',
            'port' => 25,
        ),
))

选项未通过校验

$email = new Email([
    'host'     => 'smtp.example.org',
    'username' => 'user',
    'password' => 'password',
    'port'     => '25', // 注意这里
]);

var_export($email);
PHP Fatal error:  Uncaught Symfony\Component\OptionsResolver\Exception\InvalidOptionsException: The option "port" with value "25" is expected to be of type "int", but is of type "string".

总结

个人觉得可使用该 symfony/options-resolver 组件较好的对开发第三方 sdk 的客户端类初始化参数进行校验,例如个人适配的 Yii 极光推送扩展包 - yii-jpush 中的应用。

本作品采用《CC 协议》,转载必须注明作者和本文链接
No practice, no gain in one's wit. 我的 Gitub
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
56
粉丝
126
喜欢
971
收藏
1333
排名:46
访问:15.3 万
私信
所有博文
社区赞助商