An Interest In:
Web News this Week
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
- March 28, 2024
- March 27, 2024
- March 26, 2024
June 13, 2021 11:54 am GMT
Original Link: https://dev.to/fadymr/php-create-your-own-php-options-resolver-like-symfony-4n33
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:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To