Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 13, 2021 11:54 am GMT

PHP - Create your own PHP Options Resolver ( Like Symfony )

A simple Options Resolver to processes and validates option array.

PHP version required 7.3

Now we create a OptionsResolver.php file contain the Resolver

<?phpdeclare(strict_types=1);namespace DevCoder\Resolver;final class OptionsResolver{    /**     * @var \ArrayObject<Option>     */    private $options;    public function __construct(array $options)    {        $this->options = new \ArrayObject();        foreach ($options as $option) {            $this->add($option);        }    }    public function resolve(array $options): array    {        $this->checkDiff($options);        /**         * @var Option $option         */        $optionsResolved = [];        foreach ($this->options as $option) {            $optionName = $option->getName();            if (\array_key_exists($optionName, $options)) {                $value = $options[$optionName];                if ($option->isValid($value) === false) {                    throw new \InvalidArgumentException(\sprintf('The option "%s" with value %s is invalid.', $optionName, self::formatValue($value)));                }                $optionsResolved[$optionName] = $value;                continue;            }            if ($option->hasDefaultValue()) {                $optionsResolved[$optionName] = $option->getDefaultValue();                continue;            }            throw new \InvalidArgumentException(\sprintf(                'The required option "%s" is missing.', $optionName)            );        }        return $optionsResolved;    }    private function add(Option $option): self    {        $this->options->offsetSet($option->getName(), $option);        return $this;    }    private function checkDiff(array $options): void    {        $defined = $this->options->getArrayCopy();        $diff = \array_diff_key($options, $defined);        if (\count($diff) > 0) {            throw new \InvalidArgumentException(\sprintf(                    'The option(s) "%s" do(es) not exist. Defined options are: "%s".',                    \implode(', ', \array_keys($diff)),                    \implode('", "', \array_keys($defined)))            );        }    }    private static function formatValue($value): string    {        if (\is_object($value)) {            return \get_class($value);        }        if (\is_string($value)) {            return '"' . $value . '"';        }        if (false === $value) {            return 'false';        }        if (true === $value) {            return 'true';        }        return \gettype($value);    }}

We create a Option.php file defining a option

<?phpdeclare(strict_types=1);namespace DevCoder\Resolver;final class Option{    /**     * @var string     */    private $name;    /**     * @var mixed     */    private $defaultValue;    /**     * @var bool     */    private $hasDefaultValue = false;    /**     * @var \Closure|null     */    private $validator;    /**     * Option constructor.     * @param string $name     */    public function __construct(string $name)    {        $this->name = $name;    }    public function getName(): string    {        return $this->name;    }    /**     * @return mixed     */    public function getDefaultValue()    {        return $this->defaultValue;    }    /**     * @param mixed $defaultValue     * @return Option     */    public function setDefaultValue($defaultValue): self    {        $this->hasDefaultValue = true;        $this->defaultValue = $defaultValue;        return $this;    }    public function hasDefaultValue(): bool    {        return $this->hasDefaultValue;    }    public function validator(\Closure $closure): self    {        $this->validator = $closure;        return $this;    }    public function isValid($value): bool    {        if ($this->validator instanceof \Closure) {            $validator = $this->validator;            return $validator($value);        }        return true;    }}

How to use ?
Define required options

<?phpuse DevCoder\Resolver\Option;use DevCoder\Resolver\OptionsResolver;class Database{    public function __construct(array $options = [])    {        $resolver = new OptionsResolver([            new Option('host'),            new Option('username'),            new Option('password'),            new Option('dbname'),        ]);        $this->options = $resolver->resolve($options);    }}$database = new Database([    'host' => 'localhost',    'dbname' => 'app',]);// Uncaught InvalidArgumentException: The required option "username" is missing.$database = new Database([    'host' => 'localhost',    'dbname' => 'app',    'username' => 'root',    'password' => 'root',]);// OK

Define default options

<?phpuse DevCoder\Resolver\Option;use DevCoder\Resolver\OptionsResolver;class Database{    public function __construct(array $options = [])    {        $resolver = new OptionsResolver([            (new Option('host'))->setDefaultValue('localhost'),            (new Option('username'))->setDefaultValue('root'),            (new Option('password'))->setDefaultValue('root'),            (new Option('dbname'))->setDefaultValue('app'),        ]);        /**         * array(4) {         * ["host"]=>         * string(9) "localhost"         * ["username"]=>         * string(4) "root"         * ["password"]=>         * string(4) "root"         * ["dbname"]=>         * string(3) "app"         * }         */        $this->options = $resolver->resolve($options);    }}$database = new Database([]);// OK
<?phpuse DevCoder\Resolver\Option;use DevCoder\Resolver\OptionsResolver;class Database{    public function __construct(array $options = [])    {        $resolver = new OptionsResolver([            (new Option('host'))->setDefaultValue('localhost'),            (new Option('username'))->setDefaultValue('root'),            (new Option('password'))->setDefaultValue('root'),            (new Option('dbname'))->setDefaultValue('app'),        ]);        /**         * array(4) {         * ["host"]=>         * string(9) "localhost"         * ["username"]=>         * string(4) "root"         * ["password"]=>         * string(4) "root"         * ["dbname"]=>         * string(3) "app-2"         * }         */        $this->options = $resolver->resolve($options);    }}$database = new Database([    'dbname' => 'app-2']);// OK

Non-existent options

<?phpuse DevCoder\Resolver\Option;use DevCoder\Resolver\OptionsResolver;class Database{    public function __construct(array $options = [])    {        $resolver = new OptionsResolver([            (new Option('host'))->setDefaultValue('localhost'),            (new Option('username'))->setDefaultValue('root'),            (new Option('password'))->setDefaultValue('root'),            (new Option('dbname'))->setDefaultValue('app'),        ]);        $this->options = $resolver->resolve($options);    }}$database = new Database([    'url' => 'mysql://root:root@localhost/app',]);// Uncaught InvalidArgumentException: The option(s) "url" do(es) not exist. Defined options are: "host", "username", "password", "dbname"

Validate options values

<?phpuse DevCoder\Resolver\Option;use DevCoder\Resolver\OptionsResolver;class Database{    public function __construct(array $options = [])    {        $resolver = new OptionsResolver([            (new Option('host'))                ->validator(static function($value) {                    return is_string($value);                })                ->setDefaultValue('localhost'),            (new Option('username'))                ->validator(static function($value) {                    return is_string($value);                })                ->setDefaultValue('root')            ,            (new Option('password'))                ->validator(static function($value) {                    return is_string($value);                })                ->setDefaultValue('root'),            (new Option('dbname'))                ->validator(static function($value) {                    return is_string($value);                })                ->setDefaultValue('app'),            (new Option('driver'))                ->validator(static function($value) {                    return in_array($value, ['pdo_mysql', 'pdo_pgsql']);                })                ->setDefaultValue('pdo_mysql'),        ]);        $this->options = $resolver->resolve($options);    }}$database = new Database([    'host' => '192.168.1.200',    'username' => 'root',    'password' => 'root',    'dbname' => 'my-app',    'driver' => 'pdo_sqlite']);// Uncaught InvalidArgumentException: The option "driver" with value "pdo_sqlite" is invalid.

Ideal for small project
Simple and easy!
https://github.com/devcoder-xyz/php-options-resolver


Original Link: https://dev.to/fadymr/php-create-your-own-php-options-resolver-like-symfony-4n33

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To