respect / config Goto Github PK
View Code? Open in Web Editor NEWA powerful, small, deadly simple configurator and dependency injection container DSL made to be easy
Home Page: http://respect.github.io/Config
License: Other
A powerful, small, deadly simple configurator and dependency injection container DSL made to be easy
Home Page: http://respect.github.io/Config
License: Other
I need use the same ini file to configure properties for different enviroments like Development, Staging, Live and so on.
Its normally implemented using sections name and repeating the properties into those sections.
I have(or dont find) no way to do this because sections are used to define scope for objects configuration.
Start using Respect/Doc into project, this implies into:
public
method protected
We NEED to get rid of these phpt tests until we find a way to run them in our CI environment. Our tests are failing with a Fatal error:
Class PEAR_RunTest not found.
We have now 3 tags
$ git tag -n
0.3.1 Tagging.
0.3.2 Fix PHPUnit autoloader problems
1.0.0 Up version number package.xml
I think we have to remove 1.0.0, what you guys thing?
A declarative way of creating builders with Config would be:
[router new Respect\Rest\Router]
Any call to $container->router
would lead to a new instance, avoiding reuse. Difference from current syntax is the new
keyword.
At some point, we're going to need cache for containers. I have absolutely no plans to include a cache library inside the Config's core, but the Container and Instantiators need to be cacheable, or at east serializable to a string that can be cached.
I'd have success serializing a virgin container, that haven't instantiated any instance yet (a full lazy loaded container). Quickest way to cache things I see is to flag the container/instantiator as "dirty" when some instance comes out of the lazy zone. Only "virgin" containers would be serializable.
The idea is to cache the entire container as soon as its loaded from INI files.
We also need to reduce statefullness from the component's classes. The least information we keep on properties the better for cacheability. For example, we could get rid of the Instantiator->params attribute after Instantiator parsing.
Thoughts?
We have some problems on constant parsing, since plain constants on the application side do not get evaluated. Plus, we need to support class constants inside a namespace too.
Currently config like this in php.ini:
[PDO]
db_driver = "mysql"
db_host = "localhost"
db_name = "somedb"
db_user = "root"
db_pass = ""
db_dsn = "[db_driver]:host=[db_host];dbname=[db_name]"
[Mongo]
db_driver = "mongodb"
db_host = "localhost"
db_name = "something"
db_user = "user"
db_pass = "pass"
db_server = "[db_driver]://[db_user]:[db_pass]@[db_host]/[db_name]"
returns php notice errors of undefined indexes. and in the end
db_dsn => :host=;dbname=
db_server => ://:@/
If a method has a type hint like someMethod(SomeClass $parameter)
Config just fails. Since this is a very common practice and Config will always pass an Instantiator class, I'm considering it to be a (nasty) bug.
We should validate INI files by providing a way to run something similar to a Lint tool on configuration files...
Problem: A config file cannot reference keys already loaded by another files.
Fix on Container.php:
protected function parseValue($value)
{
if ($value instanceof Instantiator) {
return $value;
} elseif (is_array($value)) {
return $this->parseSubValues($value);
} elseif (empty($value)) {
return null;
} else {
return $this->parseSingleValue($value);
}
}
Still gathering more information.
Hi. First of all, thanks for the great and simple configuration library.
In my config file:
password = 'p[a]ss[w]0rd'
Wen I load my .ini file with respect/config he try to expand the password var. And i got some not found indexes errors....
I dont want expand my password
When an instantiator is passed to another instance by parameter (and possibly by other ways) it isn't being instantiated. This was introduced after 0.3.1.
Because if it encapsulates an object that implements it, this prevents the __invoke() be runned into the object.
Almost every project I develop using Config loads files from a directory. I need to manually call loadFile() onto the same container for every file, in order to keep the file order the same.
We need to investigate a mechanism to support directory loading in the Config core. I've thought on a special, optional "manifest.ini" file which declares the methods called on the Container upon a directory instantiation.
Sample:
<?php
$c = new Container('/my/folder');
/my/folder/manifest.ini:
loadFile[] = config.ini
loadFile[] = db.ini
loadFile[] = application.ini
The following configuration does not work as expected:
myArray = [hahaha DIRECTORY_SEPARATOR hehehe]
Given the relational.ini
below:
[connection Pdo]
dsn = sqlite::memory:
[mapper Respect\Relational\Db]
connection = [connection]
Suppose $connection
is an optional parameter for the Respect\Relational\Db::__construct()
, currently if we do not define the $connection
instance Config throws a Exception. Even if the instance is not needed. We should prevent that behaviour so we can better reuse INIs.
An excpetion was throwed when try to construct an object with only one parameter at constructor and it being a reference to another object.
[productRepository \Develop\Business\Application\Product\Repositories\Product]
__construct = [[databaseConnection]]
PHP Catchable fatal error: Object of class Respect\Config\Instantiator could not be converted to string in /Users/aspinelli/Projects/tonicospinelli/developing-for-business/vendor/respect/config/library/Respect/Config/Container.php on line 310
So, works when I use property name instead of constructor call!
We should keep a nice and small subset of guidelines on wrtting INI files, mainly to be used as a requirement to make a INI a Respected, thought something like this:
It should be very useful, mainly for testing purposes, that we could inherit another configuration file, like:
database.staging.ini
[con Pdo]
dsn = mysql:host=localhost;dbname=test
username = root
password = ''
database.testing.ini
[con Pdo]
dsn = sqlite::memory:
ZendFramework does this in the same configuration file by using : in the section, this could be also be a way.
Code Coverage Report
2013-02-22 02:17:33
Summary:
Classes: 100.00% (2/2)
Methods: 100.00% (50/50)
Lines: 100.00% (255/255)
\Respect\Config::Container
Methods: 100.00% (32/32) Lines: 100.00% (170/170)
\Respect\Config::Instantiator
Methods: 100.00% (18/18) Lines: 100.00% ( 88/ 88)
@Respect See latest push to develop.
Add option the installation via composer in the README.md, or PEAR is preferential?
There's a typo in README.md
Puts within instead of wihin in section Known Limitations.
Given a config like:
[conn Pdo]
The current behavior of config is throw an Exception if we try to $container->conn
. This proposal is to add a __callable interface to Config and allow things like $container->conn(array('dsn'=>'sqlite::memory:'));'
for the above ini to work properly.
This would also be the primary way of cross-container communication:
[conn_params]
dsn = sqlite::memory:
[conn Respect\Config\Container]
loadFile[] = pdo.ini
conn[] = [conn_params]
Maybe eds could use this as well to declare inter-dependencies between files.
When some configuration depends on another instance of the same configuration file, things don't go as one would expect:
[pdo Pdo]
dsn = [dsn]
username = [db_user]
password = [db_passwd]
[connectionParams]
pdo = [pdo]
dbname = [db_name]
user = [db_user]
password = [db_passwd]
host = [db_host]
driver = [db_driver]
[config Doctrine\DBAL\Configuration]
[event Doctrine\Common\EventManager]
[cache Doctrine\Common\Cache\ArrayCache]
[config Doctrine\ORM\Tools\Setup]
createAnnotationMetadataConfiguration[] = [[orm_entity_dir], [orm_proxy_autogenerate]]
[dbal Doctrine\DBAL\DriverManager]
getConnection[] = [[connectionParams], [config], [event]]
[entityManager Doctrine\ORM\EntityManager]
create[] = [[dbal], [config], [event]]
Now, suppose I want to test the given code... it is quite normal to inject my pdo instance like that
class DoctrineTest extends \PHPUnit_Framework_TestCase
{
protected $container;
public function setUp()
{
$this->container = new Container('config.ini');
$pdo = new PDO('sqlite::memmory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->container->pdo = $pdo;
}
}
The $this->container->pdo
is actually the instance I gave, but everything that uses it inside the config is binded to the old PDO instance (the one that the Instantiator will create).
Config supports only INI-based configuration files for a lot of reasons: they're fast to parse (using the native php INI parser), easy to read and very simple in structure.
INIs simplicity allows Config to reach a very sophisticated -yet minimalistic- approach to lazy loading. Each object defined is represented by an instantiator that, when executed, loads and creates the real full object and its dependencies.
Take for instance this INI file:
[foo stdClass]
name = ImAFoo
[bar stdClass]
foo = [foo]
name = ImABar
[baz stdClass]
bar = [bar]
name = ImABaz
If you ask for a Container for $container->baz
, a chain reaction of lazy loading instantiators will eventually reach [foo].
A similar pure PHP file could be:
<?php
$container = new Container;
$container->foo = new stdClass;
$container->foo->name = 'ImAFoo';
$container->bar = new stdClass;
$container->bar->foo = $foo;
$container->bar->name = 'ImABar';
$container->baz = new stdClass;
$container->baz->bar = $bar;
$container->baz->name = 'ImABaz';
return $container;
This will instantiate every object independent of which is requested by the $container upon using, which is not optimal.
A very elegant solution would be porting this entire configuration to a lazy-loaded-aware namespace:
<?php
namespace Respect\Config\Lazy;
$container = new Container;
$container->foo = new stdClass;
$container->foo->name = 'ImAFoo';
$container->bar = new stdClass;
$container->bar->foo = $foo;
$container->bar->name = 'ImABar';
$container->baz = new stdClass;
$container->baz->bar = $bar;
$container->baz->name = 'ImABaz';
return $container;
A possible implementation would be a single Respect\Config\Lazy\Container class. This class would register a autoloader that automatically applies an alias to everything that begins with *Respect\Config\Lazy* pointing to Respect\Config\Instantiator.
The code remais the same, except for the new namespace at the top that sort of transports the entire context to a lazy-loaded sandbox.
I'm up to implement this on the few weeks. Any thoughts on that?
Needs some tests, but it seems that something like foo = [[baz]]
isn't expanding the baz
variable properly. Output should be something compatible to $container->foo = array($container->baz)
.
Problem:
[instanceof Foo\Bar]
baz = something
[lorem Foo\Ipsum]
baz = [Foo\Bar] ; not a valid name
Quick Fix:
protected function matchReference(&$value)
{
if (preg_match('/^\[([[:alnum:]\\\\]+)\]$/', $value, $match)) {
return (boolean) ($value = $match[1]);
}
}
Still digging the problem.
There is a bug when we have a "variable" with underline, defined as Object and is used in another "variable" as a property.
Eg.
; Database parameteres
db_driver = "mysql"
db_host = "localhost"
db_user = "root"
db_pass = "test"
charset = "utf8"
; Database parameteres CEP
db_name_cep = "cep"
db_dsn_cep = "[db_driver]:host=[db_host];dbname=[db_name_cep];charset=[charset]"
; Create PDO instance with database parameters
[pdo_cep PDO]
__construct = [[db_dsn_cep], [db_user], [db_pass]]
; Create Respect/Relational instance with PDO connection
[mapper_cep Respect\Relational\Mapper]
db = [pdo_cep]
The Respect\Config\Instantiator class is missing key APIs:
What about include config considered a dependency which may have values referenced and thus should be processed first. The result will be a combination of settings perhaps in the form:
$result = $config + $config_include_last + $config_include_n_desc + $config_include;
Allowing each to overwrite settings from the previous.
Now we just have to decide what an import/include looks like.
Perhaps also a header comment in order to use the same key
; import defailt.ini
or we could use an array
import = [default.ini, production.ini, app.ini]
I would rather prefer a list underneath each other though
import = $import:path/to/default.ini
matters = $import:path/to/matters.ini
not = $import:path/to/not.ini
Hmmm little weird... thoughts?
DIR for example ...
A Static Factory Instantiation only works if the returned class by the given method is the same of the calling class. This constraint is quite annoying.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.