GithubHelp home page GithubHelp logo

respect / config Goto Github PK

View Code? Open in Web Editor NEW
98.0 98.0 7.0 363 KB

A powerful, small, deadly simple configurator and dependency injection container DSL made to be easy

Home Page: http://respect.github.io/Config

License: Other

PHP 100.00%

config's People

Contributors

abdala avatar augustohp avatar diegocpires avatar diegoholiveira avatar filhodanuvem avatar henriquemoody avatar iannsp avatar nickl- avatar rogeriopradoj avatar thiagophx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

config's Issues

enviroment configuration

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.

Convert ro Respect\Doc

Start using Respect/Doc into project, this implies into:

  • Making many public method protected
  • Creating better unit tests to be used as examples
  • Adding little PHPDoc to some classes and methods

Wrong tags

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?

Support for builders

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.

Cache

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?

Constant evaluation

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.

Variable Expanding

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 => ://:@/

Support for Type Hinting

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.

Config Linter

We should validate INI files by providing a way to run something similar to a Lint tool on configuration files...

Reusing lazyLoaded instances bug

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.

I dont want expand my password

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

Lazy loading not working for parameters

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.

Loading Folders

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

Constant usage in array

The following configuration does not work as expected:

    myArray = [hahaha DIRECTORY_SEPARATOR hehehe]

Prevent InvalidArgumentException to optional arguments

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.

Instantiator not able to resolve __constructor with alone argument

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!

Config writing gruidelines

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:

  • Configuration for a specific ini should be handled by it, the more, the better. Stick with the defaults mentioned by the component, if none we fall back to PHP standards
  • Configuration variables (not instance objects) on a ini should have a namespace reflecting the INI filename to prevent conflitcs with other Respecteds

Allow configuration inheritance

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.

100% Code coverage

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.

Typo in README.md

There's a typo in README.md

Puts within instead of wihin in section Known Limitations.

Treat unset variables as parameters + Cross-container communication

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.

Lazy Load and dependency problems

When some configuration depends on another instance of the same configuration file, things don't go as one would expect:

The configuration

[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]] 

The test code

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 problem

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).

PHP-based lazy configuration

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?

Matching namespaced references

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.

Object with underline not parsed correctly

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]

Instantiator Improvements

The Respect\Config\Instantiator class is missing key APIs:

  • serialize/unserialize, so containers can be serialized and cached.
  • APIs for getConstructorParams(), getMethodCalls(), getStaticMethodCalls() and getProperties() so the Instantiator can be inspected.

Include/Import config

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?

New possible Static Factory

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.