Simon a541965113 Premier commit 10 месяцев назад
..
.github a541965113 Premier commit 10 месяцев назад
.phan a541965113 Premier commit 10 месяцев назад
docs a541965113 Premier commit 10 месяцев назад
examples a541965113 Premier commit 10 месяцев назад
src a541965113 Premier commit 10 месяцев назад
tests a541965113 Premier commit 10 месяцев назад
.gitignore a541965113 Premier commit 10 месяцев назад
.scrutinizer.yml a541965113 Premier commit 10 месяцев назад
LICENSE a541965113 Premier commit 10 месяцев назад
README.md a541965113 Premier commit 10 месяцев назад
composer.json a541965113 Premier commit 10 месяцев назад
phpdoc.xml a541965113 Premier commit 10 месяцев назад
phpunit.xml a541965113 Premier commit 10 месяцев назад

README.md

chillerlan/php-settings-container

A container class for immutable settings objects. Not a DI container. PHP 7.4+

  • SettingsContainerInterface provides immutable properties with magic getter & setter and some fancy - decouple configuration logic from your application!

PHP Version Support version license Coverage Scrunitizer Packagist downloads Continuous Integration

Documentation

Installation

requires composer

composer.json (note: replace dev-main with a version constraint, e.g. ^2.1 - see releases for valid versions)

{
	"require": {
		"php": "^7.4 || ^8.0",
		"chillerlan/php-settings-container": "dev-main"
	}
}

Profit!

Usage

The SettingsContainerInterface (wrapped inSettingsContainerAbstract ) provides plug-in functionality for immutable object properties and adds some fancy, like loading/saving JSON, arrays etc. It takes an iterable as the only constructor argument and calls a method with the trait's name on invocation (MyTrait::MyTrait()) for each used trait.

Simple usage

class MyContainer extends SettingsContainerAbstract{
	protected $foo;
	protected $bar;
}

Typed properties in PHP 7.4+:

class MyContainer extends SettingsContainerAbstract{
	protected string $foo;
	protected string $bar;
}
// use it just like a \stdClass
$container = new MyContainer;
$container->foo = 'what';
$container->bar = 'foo';

// which is equivalent to 
$container = new MyContainer(['bar' => 'foo', 'foo' => 'what']);
// ...or try
$container->fromJSON('{"foo": "what", "bar": "foo"}');


// fetch all properties as array
$container->toArray(); // -> ['foo' => 'what', 'bar' => 'foo']
// or JSON
$container->toJSON(); // -> {"foo": "what", "bar": "foo"}
// JSON via JsonSerializable
$json = json_encode($container); // -> {"foo": "what", "bar": "foo"}

//non-existing properties will be ignored:
$container->nope = 'what';

var_dump($container->nope); // -> null

Advanced usage

trait SomeOptions{
	protected $foo;
	protected $what;
	
	// this method will be called in SettingsContainerAbstract::construct()
	// after the properties have been set
	protected function SomeOptions(){
		// just some constructor stuff...
		$this->foo = strtoupper($this->foo);
	}
	
	// this method will be called from __set() when property $what is set
	protected function set_what(string $value){
		$this->what = md5($value);
	}
}

trait MoreOptions{
	protected $bar = 'whatever'; // provide default values
}
$commonOptions = [
	// SomeOptions
	'foo' => 'whatever', 
	// MoreOptions
	'bar' => 'nothing',
];

// now plug the several library options together to a single object 
$container = new class ($commonOptions) extends SettingsContainerAbstract{
	use SomeOptions, MoreOptions;
};

var_dump($container->foo); // -> WHATEVER (constructor ran strtoupper on the value)
var_dump($container->bar); // -> nothing

$container->what = 'some value';
var_dump($container->what); // -> md5 hash of "some value"

API

SettingsContainerAbstract

method return info
__construct(iterable $properties = null) - calls construct() internally after the properties have been set
(protected) construct() void calls a method with trait name as replacement constructor for each used trait
__get(string $property) mixed calls $this->{'get_'.$property}() if such a method exists
__set(string $property, $value) void calls $this->{'set_'.$property}($value) if such a method exists
__isset(string $property) bool
__unset(string $property) void
__toString() string a JSON string
toArray() array
fromIterable(iterable $properties) SettingsContainerInterface
toJSON(int $jsonOptions = null) string accepts JSON options constants
fromJSON(string $json) SettingsContainerInterface
jsonSerialize() mixed implements the JsonSerializable interface

Disclaimer

This might be either an utterly genius or completely stupid idea - you decide. However, i like it and it works. Also, this is not a dependency injection container. Stop using DI containers FFS.