Quantcast

ZF2 usage of constants in configs

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

ZF2 usage of constants in configs

Artur Bodera
Hello!

Per recent discussion on IRC we had yesterday, and previous discussions on
ML about constants and environments when working with ZF2 application, I'd
like to propose a new recommendation.

PHP global constants are not a good pattern to follow. Because
they are super-global in nature, they were used to and peppered
over ZF1 application for various purposes. The most common
constants were:

  1) APPLICATION_ENV
  2) APPLICATION_PATH
  3) __DIR__ - same as dirname(__FILE__)

ad 1)
I've personally used APPLICATION_ENV more than once in my
ZF1 application for debugging or doing short-circuiting my
development code whenever:
    if(APPLICATION_ENV == "development")

In framework context (libraries) this constant have been injected
on occasions inside Zend_* components. I don't want to repeat
previous discussion on ML why this is bad and why recent
changes to ZF2 Module Manager and MVC deprecate this
requirement.

We do not need APPLICATION_ENV constant any more, because
if index.php (or boostrap) sniffs that we are in a given environment
(for example per .htaccess setting or linux #export ENV=something)
we load different set of config files and merge those. All other
behavioral changes and branching trickles down from there.


ad 2)
We do not have an Application per se, as we had in ZF1. We have
MVC components and Application module which lives inside modules/
Configuration lives under config/, vendor stuff lives under vendor/
All other directories are miscellaneous (i.e. custom, defined by the
user and not part of any convention). This includes data dir, cache
dir, session storage dir and such.

When configuring application and modules (using Di or otherwise)
user should always define the full path. More on that below.


ad 3)
The __DIR__ constant has been used for relativity and navigating
file tree. In ZF1, such declarations were not unheard of:
    path => dirname(__FILE__) . "/../../../library/foobar/foo.php"

Because there was no other way to do it and Di was not
popularized nor implemented, the need for constants was forced
into config containers and parsers. This meant that people started
inserting constants into *.ini files, *.xml files or *.yaml. More and
more double-dots and constants were introduced. Personally I had
up to 5 path-related constants (like DATA_DIR, CACHE_DIR,
MODEL_DIR, LIBRARY_DIR etc.)



---~---~---~---~---~ THE PROPOSAL ---~---~---~---~---~
Because constants used this way are an anti-pattern, I suggest we
implement and endorse APPLICATION-ROOT-RELATIVE paths. This
is common among other app frameworks, such as drupal, wordpress
and some libraries.

Relative and absolute paths are a _natural_ mechanism implemented
in standard OS filesystem. The only question that was risen is:
"If we used relative paths, what are they relative to?

The pattern is to use "Application Root" as the base path. Example:

/var/www/html/mySite <- THIS IS APPLICATION ROOT
    ./config
    ./data
    ./vendor
    ./library
    ./modules
    ./public     <- this is DOCUMENT ROOT


As you can see, the convention now has only two definitions:
    1) APPLICATION ROOT - the main, upper path of a ZF2 application
    that holds all other directories.

    2) DOCUMENT ROOT - accessible from outside, holding resources,
    configured with httpd


All paths used throughout ZF2 config files can now be of 2 flavors:

1) RELATIVE path (to APPLICATION ROOT),  for example:
    module.cache.dir = "data/cache"
    session.save_path = "session"
    module.user.temp_path = "modules/User/temp"
    module.spriteGenerator.imagesPath = "public/img/icons"

2) ABSOLUTE path,  for example:
    module.cache.dir = "/tmp"
    session.save_path = "/var/lib/php/session"
    module.user.temp_path = "/tmp/zf2-user"
    module.spriteGenerator.imagesPath =
"/var/www/html/myOtherSite/public/img/icons"



Common questions:

Q: So how do I define DATA_PATH constant ?

A: You don't. If your module or some vendor module requires a writable
path,
you configure it in config. For example:
OLD ZF2:
    define('DATA_PATH', __DIR__ . "/data");
    modules.foo.data_path = DATA_PATH "/foomodulestuff"

NEW ZF2:   modules.foo.data_path = "data/foomodulestuff"


Q: So does that mean that if I have 10 modules that write to DATA_PATH,
and I change this path, now I have to correct configuration for all 10
modules?

A: Yes. This is explicit configuration, as opposed to using magic such as
constants and leaving it up to modules to discover paths. Paths should NOT
be discovered, but _DECLARED_ in configuration.


Q: How do a module point to files in his own directory? (modules can live
in a subdir with any name)

A: Module's src files (php) are autoloaded. If there are any other non-php
widgets that need discovering it will probably be performed with function
calls. This means, that this can happen inside module.php and you can
use __DIR__ constant there. The proposal does not limit how you use
built-in constants inside library code (or module code).


Q: How do a module point to files in other module ?

A: ModuleManager handles loading of modules, so we can create a helper
method that will resolve that path.
For example:
    $moduleAPath = ModuleManager::getModulePath("A");
    $images = $moduleAPath . "/resources/images";



Please send in your questions and comments..

Thanks for reading!


Arthur.



References:
Here is the discussion on dumping APPLICATION_ENV
http://zend-framework-community.634137.n4.nabble.com/APPLICATION-ENV-library-Zend-Module-Listener-ListenerOptions-php-td4074573.html

Here is the chat we had yesterday and my explanations on using constants
overall:
https://gist.github.com/1415354





--
      __
     /.)\   +48 695 600 936
     \(./   [hidden email]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Some thoughts on caching

Anton Stöckl

Hi there,

I would like to share some ideas about caching in ZF2.

Generally:

- I am in contact with Marc Benewitz and have a rought idea about the
new multi-layer cache architecture proposal

- I did not have the time to go though the current code in Git (we have
a 4 months old girl at home :-) ) but surely will do asap

- I'm a heavy user of caching with tags for flushing in several projects
(based on the architecture showcased in Keith Popes great book :-) )

- I have done some changes in the TwoLevels Cache in ZF 1.11 so it works
as I would expect it to (fast backend items have same lifetime as slow
backend items, including fixing a bug that gives fast backend items an
infinite lifetime)

- We're currently using MongoDB as the slow backend (with memcached as
fast BE), I have fixed and pimped a "Zend_Cache_Backend_Mongo" from Git
(by Olivier Bregeras (Stunti)) and it works excellent - MongoDB would
also make a great standalone cache, it's not _much_ slower than
memcached on reads


Here's my real point:

We're currently more and more using MongoDB as a "sort of cache layer"
(additionally to regular caching) where we don't do a "save / load /
flush" strategy but simply update the documents in the MongoDB
Collections without reading them first or flushing them. In our case -
once those documents are created - only bits of them will change from
time to time (or quite often). The main storage still is a MySQL DB and
there is no expiration on the MongoDB documents.

So I'm wondering what you guys think about adding such a "direct
document update/manipulation" strategy to the Caches in ZF2 for storage
engines that support that (some/all "no sql" DBs, Redis, File, ...)?

Regards, Anton

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

EvanDotPro
In reply to this post by Artur Bodera
Hi Artur,

Thanks for taking the time to write up this proposal and detailed
explanation of the problem we faced with constants in configs. I'll
also point out that the use of __DIR__ has been one of the primary
reasons behind all of the samples on GitHub using PHP configuration
arrays versus ini, xml, yaml, etc.

One question inline below.

On Thu, Dec 1, 2011 at 3:37 AM, Artur Bodera <[hidden email]> wrote:

> Hello!
>
> Per recent discussion on IRC we had yesterday, and previous discussions on
> ML about constants and environments when working with ZF2 application, I'd
> like to propose a new recommendation.
>
> PHP global constants are not a good pattern to follow. Because
> they are super-global in nature, they were used to and peppered
> over ZF1 application for various purposes. The most common
> constants were:
>
>  1) APPLICATION_ENV
>  2) APPLICATION_PATH
>  3) __DIR__ - same as dirname(__FILE__)
>
> ad 1)
> I've personally used APPLICATION_ENV more than once in my
> ZF1 application for debugging or doing short-circuiting my
> development code whenever:
>    if(APPLICATION_ENV == "development")
>
> In framework context (libraries) this constant have been injected
> on occasions inside Zend_* components. I don't want to repeat
> previous discussion on ML why this is bad and why recent
> changes to ZF2 Module Manager and MVC deprecate this
> requirement.
>
> We do not need APPLICATION_ENV constant any more, because
> if index.php (or boostrap) sniffs that we are in a given environment
> (for example per .htaccess setting or linux #export ENV=something)
> we load different set of config files and merge those. All other
> behavioral changes and branching trickles down from there.
>
>
> ad 2)
> We do not have an Application per se, as we had in ZF1. We have
> MVC components and Application module which lives inside modules/
> Configuration lives under config/, vendor stuff lives under vendor/
> All other directories are miscellaneous (i.e. custom, defined by the
> user and not part of any convention). This includes data dir, cache
> dir, session storage dir and such.
>
> When configuring application and modules (using Di or otherwise)
> user should always define the full path. More on that below.
>
>
> ad 3)
> The __DIR__ constant has been used for relativity and navigating
> file tree. In ZF1, such declarations were not unheard of:
>    path => dirname(__FILE__) . "/../../../library/foobar/foo.php"
>
> Because there was no other way to do it and Di was not
> popularized nor implemented, the need for constants was forced
> into config containers and parsers. This meant that people started
> inserting constants into *.ini files, *.xml files or *.yaml. More and
> more double-dots and constants were introduced. Personally I had
> up to 5 path-related constants (like DATA_DIR, CACHE_DIR,
> MODEL_DIR, LIBRARY_DIR etc.)
>
>
>
> ---~---~---~---~---~ THE PROPOSAL ---~---~---~---~---~
> Because constants used this way are an anti-pattern, I suggest we
> implement and endorse APPLICATION-ROOT-RELATIVE paths. This
> is common among other app frameworks, such as drupal, wordpress
> and some libraries.
>
> Relative and absolute paths are a _natural_ mechanism implemented
> in standard OS filesystem. The only question that was risen is:
> "If we used relative paths, what are they relative to?
>
> The pattern is to use "Application Root" as the base path. Example:
>
> /var/www/html/mySite <- THIS IS APPLICATION ROOT
>    ./config
>    ./data
>    ./vendor
>    ./library
>    ./modules
>    ./public     <- this is DOCUMENT ROOT
>
>
> As you can see, the convention now has only two definitions:
>    1) APPLICATION ROOT - the main, upper path of a ZF2 application
>    that holds all other directories.
>
>    2) DOCUMENT ROOT - accessible from outside, holding resources,
>    configured with httpd
>
>
> All paths used throughout ZF2 config files can now be of 2 flavors:
>
> 1) RELATIVE path (to APPLICATION ROOT),  for example:
>    module.cache.dir = "data/cache"
>    session.save_path = "session"
>    module.user.temp_path = "modules/User/temp"
>    module.spriteGenerator.imagesPath = "public/img/icons"
>
> 2) ABSOLUTE path,  for example:
>    module.cache.dir = "/tmp"
>    session.save_path = "/var/lib/php/session"
>    module.user.temp_path = "/tmp/zf2-user"
>    module.spriteGenerator.imagesPath =
> "/var/www/html/myOtherSite/public/img/icons"
>
>
>
> Common questions:
>
> Q: So how do I define DATA_PATH constant ?
>
> A: You don't. If your module or some vendor module requires a writable
> path,
> you configure it in config. For example:
> OLD ZF2:
>    define('DATA_PATH', __DIR__ . "/data");
>    modules.foo.data_path = DATA_PATH "/foomodulestuff"
>
> NEW ZF2:   modules.foo.data_path = "data/foomodulestuff"
>
>
> Q: So does that mean that if I have 10 modules that write to DATA_PATH,
> and I change this path, now I have to correct configuration for all 10
> modules?
>
> A: Yes. This is explicit configuration, as opposed to using magic such as
> constants and leaving it up to modules to discover paths. Paths should NOT
> be discovered, but _DECLARED_ in configuration.
>
>
> Q: How do a module point to files in his own directory? (modules can live
> in a subdir with any name)
>
> A: Module's src files (php) are autoloaded. If there are any other non-php
> widgets that need discovering it will probably be performed with function
> calls. This means, that this can happen inside module.php and you can
> use __DIR__ constant there. The proposal does not limit how you use
> built-in constants inside library code (or module code).

Just to clarify: in this proposal, anything requiring relative paths
to a module's own path would have to be done in function calls
(perhaps in Module.php)? We would no longer put any relative paths in
the module config.

Here are some examples of where __DIR__ is used in configs as of writing this:

https://github.com/zendframework/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php#L17
https://github.com/EvanDotPro/EdpUser/blob/master/config/module.config.php#L84

So those instances would have to be handled within Module.php (or some
non-config module code) instead of defined in the config file(s)?

--
Evan Coury

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

ralphschindler
In reply to this post by Artur Bodera
Some quick history and problems:

APPLICATION_PATH constant was used b/c we settled on shipping the main
configuration file as an INI files.  In PHP, ini files can resolve only
constants from the outside.  The same limitation exists in json, xml and
yaml TMK.

So, that means "relative paths" have to become a first class citizen in
some ZF component that can do the resolution.  Why?

B/c at the PHP layer, relative is always relative to the current working
directory - which, for the web app entry point will be public/index.php.

A problem exists when you run your tests, the relative directory there
will be tests/ (set by PHPUnit to the best of my knowledge).  Another
problem exists when talking about writing CLI tools - what is the CWD
there? Where the command was executed from / or where the "application
root is?"

So, it sounds like we need to be doing a chdir() somewhere.

-ralph

On 12/1/11 4:37 AM, Artur Bodera wrote:

> Hello!
>
> Per recent discussion on IRC we had yesterday, and previous discussions on
> ML about constants and environments when working with ZF2 application, I'd
> like to propose a new recommendation.
>
> PHP global constants are not a good pattern to follow. Because
> they are super-global in nature, they were used to and peppered
> over ZF1 application for various purposes. The most common
> constants were:
>
>    1) APPLICATION_ENV
>    2) APPLICATION_PATH
>    3) __DIR__ - same as dirname(__FILE__)
>
> ad 1)
> I've personally used APPLICATION_ENV more than once in my
> ZF1 application for debugging or doing short-circuiting my
> development code whenever:
>      if(APPLICATION_ENV == "development")
>
> In framework context (libraries) this constant have been injected
> on occasions inside Zend_* components. I don't want to repeat
> previous discussion on ML why this is bad and why recent
> changes to ZF2 Module Manager and MVC deprecate this
> requirement.
>
> We do not need APPLICATION_ENV constant any more, because
> if index.php (or boostrap) sniffs that we are in a given environment
> (for example per .htaccess setting or linux #export ENV=something)
> we load different set of config files and merge those. All other
> behavioral changes and branching trickles down from there.
>
>
> ad 2)
> We do not have an Application per se, as we had in ZF1. We have
> MVC components and Application module which lives inside modules/
> Configuration lives under config/, vendor stuff lives under vendor/
> All other directories are miscellaneous (i.e. custom, defined by the
> user and not part of any convention). This includes data dir, cache
> dir, session storage dir and such.
>
> When configuring application and modules (using Di or otherwise)
> user should always define the full path. More on that below.
>
>
> ad 3)
> The __DIR__ constant has been used for relativity and navigating
> file tree. In ZF1, such declarations were not unheard of:
>      path =>  dirname(__FILE__) . "/../../../library/foobar/foo.php"
>
> Because there was no other way to do it and Di was not
> popularized nor implemented, the need for constants was forced
> into config containers and parsers. This meant that people started
> inserting constants into *.ini files, *.xml files or *.yaml. More and
> more double-dots and constants were introduced. Personally I had
> up to 5 path-related constants (like DATA_DIR, CACHE_DIR,
> MODEL_DIR, LIBRARY_DIR etc.)
>
>
>
> ---~---~---~---~---~ THE PROPOSAL ---~---~---~---~---~
> Because constants used this way are an anti-pattern, I suggest we
> implement and endorse APPLICATION-ROOT-RELATIVE paths. This
> is common among other app frameworks, such as drupal, wordpress
> and some libraries.
>
> Relative and absolute paths are a _natural_ mechanism implemented
> in standard OS filesystem. The only question that was risen is:
> "If we used relative paths, what are they relative to?
>
> The pattern is to use "Application Root" as the base path. Example:
>
> /var/www/html/mySite<- THIS IS APPLICATION ROOT
>      ./config
>      ./data
>      ./vendor
>      ./library
>      ./modules
>      ./public<- this is DOCUMENT ROOT
>
>
> As you can see, the convention now has only two definitions:
>      1) APPLICATION ROOT - the main, upper path of a ZF2 application
>      that holds all other directories.
>
>      2) DOCUMENT ROOT - accessible from outside, holding resources,
>      configured with httpd
>
>
> All paths used throughout ZF2 config files can now be of 2 flavors:
>
> 1) RELATIVE path (to APPLICATION ROOT),  for example:
>      module.cache.dir = "data/cache"
>      session.save_path = "session"
>      module.user.temp_path = "modules/User/temp"
>      module.spriteGenerator.imagesPath = "public/img/icons"
>
> 2) ABSOLUTE path,  for example:
>      module.cache.dir = "/tmp"
>      session.save_path = "/var/lib/php/session"
>      module.user.temp_path = "/tmp/zf2-user"
>      module.spriteGenerator.imagesPath =
> "/var/www/html/myOtherSite/public/img/icons"
>
>
>
> Common questions:
>
> Q: So how do I define DATA_PATH constant ?
>
> A: You don't. If your module or some vendor module requires a writable
> path,
> you configure it in config. For example:
> OLD ZF2:
>      define('DATA_PATH', __DIR__ . "/data");
>      modules.foo.data_path = DATA_PATH "/foomodulestuff"
>
> NEW ZF2:   modules.foo.data_path = "data/foomodulestuff"
>
>
> Q: So does that mean that if I have 10 modules that write to DATA_PATH,
> and I change this path, now I have to correct configuration for all 10
> modules?
>
> A: Yes. This is explicit configuration, as opposed to using magic such as
> constants and leaving it up to modules to discover paths. Paths should NOT
> be discovered, but _DECLARED_ in configuration.
>
>
> Q: How do a module point to files in his own directory? (modules can live
> in a subdir with any name)
>
> A: Module's src files (php) are autoloaded. If there are any other non-php
> widgets that need discovering it will probably be performed with function
> calls. This means, that this can happen inside module.php and you can
> use __DIR__ constant there. The proposal does not limit how you use
> built-in constants inside library code (or module code).
>
>
> Q: How do a module point to files in other module ?
>
> A: ModuleManager handles loading of modules, so we can create a helper
> method that will resolve that path.
> For example:
>      $moduleAPath = ModuleManager::getModulePath("A");
>      $images = $moduleAPath . "/resources/images";
>
>
>
> Please send in your questions and comments..
>
> Thanks for reading!
>
>
> Arthur.
>
>
>
> References:
> Here is the discussion on dumping APPLICATION_ENV
> http://zend-framework-community.634137.n4.nabble.com/APPLICATION-ENV-library-Zend-Module-Listener-ListenerOptions-php-td4074573.html
>
> Here is the chat we had yesterday and my explanations on using constants
> overall:
> https://gist.github.com/1415354
>
>
>
>
>


--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Artur Bodera
On Thu, Dec 1, 2011 at 7:03 PM, Ralph Schindler <[hidden email]>wrote:

> Some quick history and problems:
>  APPLICATION_PATH constant was used b/c we settled on shipping the main
> configuration file as an INI files.  In PHP, ini files can resolve only
> constants from the outside.  The same limitation exists in json, xml and
> yaml TMK.
>  So, that means "relative paths" have to become a first class citizen in
> some ZF component that can do the resolution.  Why?
>

IMO path resolution should be performed by the OS, not components. IMO it
is weird for any ZF component to perform regex checks on paths, resolve
them or manipulate them. This includes view scripts stack - this should
also rely on relative behavior. For example:
    $stack = new Zend\View\TemplatePathStack();

    // add main module view scripts path
    $stack->addPath("modules/application/views/scripts");  <-- relative to
APP ROOT

    // add absolute path from another project
    $stack->addPath("/var/www/html/otherSite/templates"); <-- absolute

    // add view scripts for a module
    $modulePath = ModuleManager::getModulePath("FooModule");
    $stack->addPath($modulePath . "/views/scripts");




>  B/c at the PHP layer, relative is always relative to the current working
> directory - which, for the web app entry point will be public/index.php.
>  A problem exists when you run your tests, the relative directory there
> will be tests/ (set by PHPUnit to the best of my knowledge).  Another
> problem exists when talking about writing CLI tools - what is the CWD
> there? Where the command was executed from / or where the "application root
> is?"
>  So, it sounds like we need to be doing a chdir() somewhere.
>

You are correct.

In case DOCUMENT ROOT ("public" directory) is a descendant of APPLICATION
ROOT, you perform
    $oldCwd = getcwd();
    chdir(__DIR__."/..");

    // ..... bootstrap and run ZF2 app. .

    chdir($oldCwd);

This is very common operation for many linux shell commands and scripts.

In case you are running a CLI command (for example with new Zend\Tool
successor), your boostrap (or CLI handler) have to chdir() into APPLICATION
ROOT. Same applies to running tests. You have to chdir() to APPLICATION
ROOT, but I don't see any ambiguity here. The way I see it, "tests"
directory lives always under APPLICATION ROOT, so the init.php (or other
bootstrap file) will just chdir there.

Actually, this convention simplifies a lot of things, while avoiding some
pitfalls (like trying to walk around modules' paths, which can be about
anything, including loading shared modules from some absolute path).


A.

--
      __
     /.)\   +48 695 600 936
     \(./   [hidden email]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Gregory
Outside of config files I don't think constants should be used or
encouraged. It may end up that they shouldn't be used in config files
either, rather some kind of token/variable that will be replaced
accordingly.

If we we're to end up having constants, can they be all be prefixed
the same, e.g APPLICATION_.

I would also suggest using APPLICATION_PUBLIC_DIR, since DOCUMENT_ROOT
might be confusing or require further thought/communication when the
project's public directory is not the same as the Apache DocumentRoot.

Reading this thread, and others has made me question:

"What does it mean to register a module in the application config?"

Otherwise I'm leading more to the impression that all modules will
need to be registered?

Either way, as long as in the main config we can override any path
that a module might specify locally, then it should be fine.

I also have tried to consider what it means for a module to have a
config file. I'm still trying to determine whether any of those
parameters would _not_ be for the sole use of that modules DI
components. Since most configuration parameters are always targeted at
specific components for them to use/return, e.g most of them are
ideally not actually used globally even though they might exist in a
global config.


--
Greg

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Artur Bodera
On Thu, Dec 1, 2011 at 11:34 PM, Greg <[hidden email]> wrote:

> Outside of config files I don't think constants should be used or
> encouraged. It may end up that they shouldn't be used in config files
> either, rather some kind of token/variable that will be replaced
> accordingly.
>  If we we're to end up having constants, can they be all be prefixed
> the same, e.g APPLICATION_.
>

That's not what's been suggested.
There should _NOT_ be any constants inside config files!

Constants are a php language feature and are mostly unsupported in config
formats... unless you hack it (parse strings, regex match, extract tokens,
translate/map, validate, prefix etc.).


Because (among others):
1) It's better to endorse to users that they define their paths explicitly
and not leave it up to components/modules to automagically discover
anything or resolve from a constant.

2) Why use a constant if you use it only in one place? (i.e. it's equal to
copy-paste)

3) Configs should be static in nature (like in a "static string" as opposed
to "expression"). If a path changes, go and edit your config. If you need
dynamic discovery (because your paths change
constantly) use php code (directoryiterator, glob, etc.) inside bootstrap
or init() to discover paths and inject those directly into components.

4) Relativity in paths matters, but in ZF1 most of the time you want
everything relative to APPLICATION_PATH. Because we do not have
"/application" any more (as it was in ZF1), then the most solid path you
can use is the main, upmost application dir (application root). Given than
we just chdir() into application root, you can use relative (short) paths
for everything.

5) The forementioned relativity and chdir() is especially important once we
use the glob feature. Config files can now live in many different
directories and are merged together. This means that __DIR__ is useless in
this scenario and paths like "../../../../" should be avoided and strongly
discouraged. Actually, if you are after chdir() and inside AppRoot dir, you
do not need double-dot ".." any more.

6) Tokens (poor-mans constants) are bad, expensive, their naming and
resolution pattern might be questionable and do not bring much value. You
can have the same after chdir() and with some discipline in defining paths
for components (i.e. DATA_DIR, why not DATA_PATH ? I've been personally
using this constant in zf1 and prepending here and there in my *.php config
files, but I actually NEVER changed this path, ever. Even If I did, I don't
need constant for that - I could just use IDE find-replace-in-files
function on config/*.php)

7) All app directories are optional, including vendor/ modules/ library/
etc. One can have as many or as few of those, as everything is
configurable. There are only recommendations, but not standards in this
manner, so again - it's better for users that they defined their paths by
hand, i.e. cache.dir = "data/cache"

8) We are slowly gearing towards some ZF2 convenience tools, such as module
installer/manager. This means that it might semi-automatically handle the
process of installation and configuration. If you tell it, that you keep
all the data inside "data/", it might install your new modules into vendor/
and automatically configure them with "data/somemodule" (so called
configuration templates, which might contain some tokens and discovery
logic)


A.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

weierophinney
Administrator
In reply to this post by Artur Bodera
Late to the thread, as I was travelling yesterday. I have a number of
comments, inline below.

-- Artur Bodera <[hidden email]> wrote
(on Thursday, 01 December 2011, 11:37 AM +0100):

> Per recent discussion on IRC we had yesterday, and previous discussions on
> ML about constants and environments when working with ZF2 application, I'd
> like to propose a new recommendation.
>
> PHP global constants are not a good pattern to follow. Because
> they are super-global in nature, they were used to and peppered
> over ZF1 application for various purposes. The most common
> constants were:
>
>   1) APPLICATION_ENV
>   2) APPLICATION_PATH
>   3) __DIR__ - same as dirname(__FILE__)

First, a point of clarification: These are not equivalent.

APPLICATION_ENV and APPLICATION_PATH are user-set constants. __DIR__ is
a PHP magic constant, and I'd argue it's not in the same league at all.
It's used to determine where the current script resides.

Prior to PHP 5.3, it was impossible to determine where a file lived
without a function call (dirname(__FILE__)). __DIR__ solves that, and
also does so in a more succinct way.

So, I personally feel we should separate discussion of these, as it's
comparing apples and oranges.

> ad 1)
> I've personally used APPLICATION_ENV more than once in my
> ZF1 application for debugging or doing short-circuiting my
> development code whenever:
>     if(APPLICATION_ENV == "development")
>
> In framework context (libraries) this constant have been injected
> on occasions inside Zend_* components. I don't want to repeat
> previous discussion on ML why this is bad and why recent
> changes to ZF2 Module Manager and MVC deprecate this
> requirement.
>
> We do not need APPLICATION_ENV constant any more, because
> if index.php (or boostrap) sniffs that we are in a given environment
> (for example per .htaccess setting or linux #export ENV=something)
> we load different set of config files and merge those. All other
> behavioral changes and branching trickles down from there.

I agree here -- with DI/Service Location, we have the ability to inject
this. The one place it could be problematic still is view scripts, as
this would require injecting the env into the view variables. However,
we can likely come up with reasonable conventions surrounding that as
well.

> ad 2)
> We do not have an Application per se, as we had in ZF1. We have
> MVC components and Application module which lives inside modules/
> Configuration lives under config/, vendor stuff lives under vendor/
> All other directories are miscellaneous (i.e. custom, defined by the
> user and not part of any convention). This includes data dir, cache
> dir, session storage dir and such.
>
> When configuring application and modules (using Di or otherwise)
> user should always define the full path. More on that below.

I disagree. Full path (if you're talking realpath) is something that is
going to be problematic when it comes to working in multiple
environments. Paths need to be relative to somewhere -- the application
root, the module root, the document root.

I think what you're trying to suggest is that those "root" values be
injected somehow, or calculated.

We've been doing that with the APPLICATION_PATH constant, as our
configuration formats will take into account constant values, which
means that parsing a config file gives us full paths. So, I guess I'm a
little confused as to what you want to do differently. That is, until I
read the next point:

> ad 3)
> The __DIR__ constant has been used for relativity and navigating
> file tree. In ZF1, such declarations were not unheard of:
>     path => dirname(__FILE__) . "/../../../library/foobar/foo.php"
>
> Because there was no other way to do it and Di was not
> popularized nor implemented, the need for constants was forced
> into config containers and parsers. This meant that people started
> inserting constants into *.ini files, *.xml files or *.yaml. More and
> more double-dots and constants were introduced. Personally I had
> up to 5 path-related constants (like DATA_DIR, CACHE_DIR,
> MODEL_DIR, LIBRARY_DIR etc.)

I'd argue __DIR__ has nothing to do with these constants you discuss at
the end. Also, I'd argue if you're using __DIR__ in your configuration
to get to a path outside the module, you're doing something wrong
already (as you can't rely on structure outside the module).

The question, then, is, how do we calculate these relative paths for
common tasks (cache, data, etc.)?

I agree that in _code_, we shouldn't be relying on constants. But in
_configuration_, I'm not sure why you're so against them, since they
allow for calculating the real path from a relative path dynamically.

I'm not sold on your proposal at all. More details below.

> ---~---~---~---~---~ THE PROPOSAL ---~---~---~---~---~
> Because constants used this way are an anti-pattern,

 I'm not clear on why using constants in the configuration files is an
"anti-pattern." You have asserted this as fact, without any references
to discussions, blog posts, articles, whatever -- referencing an IRC
discussion where you were the only one asserting it does not count;
that's still in the realm of personal opinion, and not general
acceptance.

It's clear that your _personal_ preference is not to use them, but
you're not indicating what is _inherently_ wrong with them.

> I suggest we implement and endorse APPLICATION-ROOT-RELATIVE paths.
> This is common among other app frameworks, such as drupal, wordpress
> and some libraries.

That was kind of the point of the APPLICATION_PATH constant -- to create
paths relative to the application root.

To be honest, I never created other constants -- if I needed to specify
a cache directory, I used:

    APPLICATION_PATH "cache/segmentname"

Same thing with data, etc. Everything is relative to the application
root, which is what you suggest as well.

> Relative and absolute paths are a _natural_ mechanism implemented
> in standard OS filesystem. The only question that was risen is:
> "If we used relative paths, what are they relative to?

I'd argue we already _are_ using relative paths. See my argument above.

> The pattern is to use "Application Root" as the base path. Example:
>
> /var/www/html/mySite <- THIS IS APPLICATION ROOT
>     ./config
>     ./data
>     ./vendor
>     ./library
>     ./modules
>     ./public     <- this is DOCUMENT ROOT
>
>
> As you can see, the convention now has only two definitions:
>     1) APPLICATION ROOT - the main, upper path of a ZF2 application
>     that holds all other directories.
>
>     2) DOCUMENT ROOT - accessible from outside, holding resources,
>     configured with httpd

I'm not seeing anything different than what we've had standardized in
either ZF1 or ZF2 at this time.

> All paths used throughout ZF2 config files can now be of 2 flavors:
>
> 1) RELATIVE path (to APPLICATION ROOT),  for example:
>     module.cache.dir = "data/cache"
>     session.save_path = "session"
>     module.user.temp_path = "modules/User/temp"
>     module.spriteGenerator.imagesPath = "public/img/icons"
>
> 2) ABSOLUTE path,  for example:
>     module.cache.dir = "/tmp"
>     session.save_path = "/var/lib/php/session"
>     module.user.temp_path = "/tmp/zf2-user"
>     module.spriteGenerator.imagesPath =
> "/var/www/html/myOtherSite/public/img/icons"

As I noted before, absolute paths are problematic unless you know
exactly all the environments you'll be using. That said, it's trivial to
add new sections and override those paths.

Also, as noted before, regarding paths relative to the application root,
we're already doing so. The difference right now is that we use constant
values in the configuration files to provide the application root as a
prefix to the path. If this is the only place those constants are
evaluated, I don't see the problem.

My big question to you is: how do you plan to inform the various
configurable classes as to where the application path lives?

Let me explain.

In your example (1) from above, let's look at this:

    module.cache.dir = "data/cache"

Previously, we would have had:

    module.cache.dir = APPLICATION_PATH "/data/cache"

When the cache object gets injected with this configuration, it knows
exactly where to store things -- because the path is an absolute path.

In your solution, it gets simply "data/cache" -- which means that we
have to now provide the cache object ANOTHER piece of information: the
application path.

How exactly do you plan to do that?

I've seen later in the thread you recommend that as the application
begins, we do the following in our index.php:

    chdir(__DIR__ . '/../);

But that means that code like the cache above then needs to do this:

    $dir = getcwd() . '/' . $options['dir'];

I'd actually call _THAT_ an anti-pattern, as the component is then
making an assumption about the directory structure and execution
environment. Previously, it simply received a path, and used it -- which
is good de-coupling.

The other option is to inject it. But that means that any class that has
configurable paths now has an additional option it needs to receive, and
additional logic it needs to invoke to resolve the relative path.
Honestly, this seems like pointless work.

> Common questions:

<snip>

> Q: So does that mean that if I have 10 modules that write to DATA_PATH,
> and I change this path, now I have to correct configuration for all 10
> modules?
>
> A: Yes. This is explicit configuration, as opposed to using magic such as
> constants and leaving it up to modules to discover paths. Paths should NOT
> be discovered, but _DECLARED_ in configuration.

I'm going to say it again: using APPLICATION_PATH in config files is
still declarative. It's not a discovered path, it's a declared path.
You're declaring the value of APPLICATION_PATH, and simply using it to
prefix paths relative to it within your declarative configuration.

<snip>

> Q: How do a module point to files in other module ?
>
> A: ModuleManager handles loading of modules, so we can create a helper
> method that will resolve that path.
> For example:
>     $moduleAPath = ModuleManager::getModulePath("A");
>     $images = $moduleAPath . "/resources/images";

Actually, there's not even a need for a helper; you can get this through
reflection:

    $r    = new \ReflectionClass('Module\A');
    $path = dirname($r->getFileName());

We _could_ create a helper, but all it would be doing is the above.
Considering you'd need an import statement for the ModuleManager, you
end up with two lines of code either way. :)

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Artur Bodera
On Fri, Dec 2, 2011 at 5:34 PM, Matthew Weier O'Phinney <[hidden email]>wrote:

> My big question to you is: how do you plan to inform the various
> configurable classes as to where the application path lives?
>  Let me explain.
>  In your example (1) from above, let's look at this:
>      module.cache.dir = "data/cache"
>  Previously, we would have had:
>      module.cache.dir = APPLICATION_PATH "/data/cache"
>  When the cache object gets injected with this configuration, it knows
> exactly where to store things -- because the path is an absolute path.
>  In your solution, it gets simply "data/cache" -- which means that we
> have to now provide the cache object ANOTHER piece of information: the
> application path.
>  How exactly do you plan to do that?
>

I believe you've not understood me fully. Answering the above and snippet
below might bring you closer to the picture I'm paiting here.

First:
Absolute paths are an important option for some people. I've
brought that up only to describe it as a possibility. I do not
endorse it and know how envs can change. Absolute paths
are usually used for shared-dir resources, global temporary
dirs and (possibly in near future) shared zf2 modules.



> I've seen later in the thread you recommend that as the application
> begins, we do the following in our index.php:
>      chdir(__DIR__ . '/../);
>  But that means that code like the cache above then needs to do this:
>      $dir = getcwd() . '/' . $options['dir'];


You DON'T do this.

Here's an example flow:
[ CWD ] = current working dir

1) [unknown]  php script is invoked by the SAPI/CGI/CLI or other higher
layer - we cannot be sure of CWD because of different implementations.
2) [unknown]  inside /var/www/html/sitepublic/index.php  :<?php
chdir(__DIR__ . "/../");
3) [/var/www/html/site]  bootstrapping and loading of configs
4) [/var/www/html/site]  cache backend receives the following relative
path: cache.file = "data/cache/cache.dat"
5) [/var/www/html/site] <?php fopen("data/cache/cache.dat","rw") ?> --
equals posix open("/var/www/html/site/data/cache/cache.dat", O_RDWR...

Path resolution is up to the system. chdir() guarantees that all
subsequent FS calls will be relative to CWD. All paths will work
as expected and constants in config files become redundant.


In separate message I've outlined why tokenizing config files is
not a good idea. To sum up - if we have a common path which
we chdir() into, we do not need token parsing or userland
constants any more.




A.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

weierophinney
Administrator
-- Artur Bodera <[hidden email]> wrote
(on Friday, 02 December 2011, 06:20 PM +0100):
> On Fri, Dec 2, 2011 at 5:34 PM, Matthew Weier O'Phinney <[hidden email]>wrote:
<snip>

> > I've seen later in the thread you recommend that as the application
> > begins, we do the following in our index.php:
> >      chdir(__DIR__ . '/../);
> >  But that means that code like the cache above then needs to do this:
> >      $dir = getcwd() . '/' . $options['dir'];
>
>
> You DON'T do this.
>
> Here's an example flow:
> [ CWD ] = current working dir
>
> 1) [unknown]  php script is invoked by the SAPI/CGI/CLI or other higher
> layer - we cannot be sure of CWD because of different implementations.
> 2) [unknown]  inside /var/www/html/sitepublic/index.php  :<?php
> chdir(__DIR__ . "/../");
> 3) [/var/www/html/site]  bootstrapping and loading of configs
> 4) [/var/www/html/site]  cache backend receives the following relative
> path: cache.file = "data/cache/cache.dat"
> 5) [/var/www/html/site] <?php fopen("data/cache/cache.dat","rw") ?> --
> equals posix open("/var/www/html/site/data/cache/cache.dat", O_RDWR...
>
> Path resolution is up to the system. chdir() guarantees that all
> subsequent FS calls will be relative to CWD. All paths will work
> as expected and constants in config files become redundant.

Argh, right -- forgot about that detail. I'll concede that.

There's another detail, however, that you're missing: what about scripts
other than public/index.php? For instance, if I had a "console" script
in the application root? or a script under "scripts/"? or in a module?
These then need to know where they live in relation to the application
root.

That said, they'd need to set the APPLICATION_ENV constant anyways, so
this may just be the same problem with a different disguise.

The main thing is making sure this is well-documented, to ensure that
those writing functionality that may need to read from/write to the
filesystem know how to properly setup the environment to allow this.

> In separate message I've outlined why tokenizing config files is
> not a good idea. To sum up - if we have a common path which
> we chdir() into, we do not need token parsing or userland
> constants any more.

True -- but it's also a nice capability to allow. If anything, we tend
to err on the side of flexibility in ZF.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Artur Bodera
On Mon, Dec 5, 2011 at 6:51 PM, Matthew Weier O'Phinney <[hidden email]>wrote:

> There's another detail, however, that you're missing: what about scripts
> other than public/index.php? For instance, if I had a "console" script
> in the application root? or a script under "scripts/"? or in a module?
> These then need to know where they live in relation to the application
> root.
>

They do, but that is the main advantage of the proposed method.
In modern php applications there is a single point of entry (or just a few,
such as one for php sapi, one for cli, one for testing).

This means that chdirs() is done only ONCE and further scanning and
resolving
is not required, as everything is defined by the user from there.
(unless there are special-cases which require scanning or other path
magic nevertheless)




That said, they'd need to set the APPLICATION_ENV constant anyways, so
> this may just be the same problem with a different disguise.
>

You don't, actually.

In case you have several points of entry (i.e. CLI and public/index.php)
then
you can put your bootstrapping/configuration into a shared file, for example
init.php. This has been proposed some time ago and I've been using it for
quite some time.

This means:

./init.php:
<?php

chdir(__DIR__);
require_once 'vendor/ZendFramework/library/Zend/Loader/AutoloaderFactory.php';
Zend\Loader\AutoloaderFactory::factory(array('Zend\Loader\StandardAutoloader'
=> array()));
$appConfig = include 'config/application.config.php';
$moduleLoader = new Zend\Loader\ModuleAutoloader($appConfig['module_paths']);
$moduleLoader->register();
$moduleManager = new Zend\Module\Manager($appConfig['modules']);
$listenerOptions = new
Zend\Module\Listener\ListenerOptions($appConfig['module_listener_options']);
$moduleManager->setDefaultListenerOptions($listenerOptions);
$moduleManager->getConfigListener()->addConfigGlobPath('config/autoload/*.config.php');

// load ENV-specific config files
$appEnv = getenv('environment']) ? getenv('environment']) :
'production';   // we don't need it later!
$moduleManager->getConfigListener()->addConfigGlobPath('config/autoload/'.$appEnv.'/*.config.php');


./public/index.php
<?php

require_once __DIR__.'/../init.php';

// load web-specific config
$moduleManager->getConfigListener()->addConfigGlobPath('config/autoload/web/*.config.php');

// load modules
$moduleManager->loadModules();

// Create application, bootstrap, and run
$bootstrap   = new Zend\Mvc\Bootstrap($moduleManager->getMergedConfig());
$application = new Zend\Mvc\Application;
$bootstrap->bootstrap($application);
$application->run()->send();


./shell.php
<?php

require_once __DIR__.'/init.php';

// load CLI-specific config
$moduleManager->getConfigListener()->addConfigGlobPath('config/autoload/console/*.config.php');

// load modules
$moduleManager->loadModules();

// Create application, bootstrap
$bootstrap   = new Zend\Mvc\Bootstrap($moduleManager->getMergedConfig());
$application = new Zend\Mvc\Application;
$bootstrap->bootstrap($application);

// Handle CLI commands
Zend\Tool\Router::run();  // .. or whatever :)



The main thing is making sure this is well-documented, to ensure that
> those writing functionality that may need to read from/write to the
> filesystem know how to properly setup the environment to allow this.
>

As everything :-)

I believe having a common chdir() path is even easier than explaining
to newbies what __DIR__, APPLICATION_PATH, DATA_DIR and other
nuggets are and what are the differences..

With common path you just :
"type in the path you want, relative from the main dir"


> True -- but it's also a nice capability to allow. If anything, we tend
> to err on the side of flexibility in ZF.
>

Implicit token scanning for each and every config string? That's not
flexibility, that's madness :-)

If you really need that for some Special Tactics [tm] , you could still
do parsing with some component that will process those text files and
then feed it to config listener.

Actually we can't stop people from defining 50 constants inside public.php
and sprinkling them all over the place, but at least there won't be any
constant-related requirement any more (i.e. the existence of
APPLICATION_ENV or APPLICATION_DIR/_PATH );


The above is a shift in paradigm. But so are other zf2 changes.
APPLICATION_ENV is no more, because we have multiple, merged
config files. There are modules, there is no application/ dir, etc.



A.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

weierophinney
Administrator
-- Artur Bodera <[hidden email]> wrote
(on Tuesday, 06 December 2011, 07:47 PM +0100):

> On Mon, Dec 5, 2011 at 6:51 PM, Matthew Weier O'Phinney <[hidden email]>wrote:
> > True -- but it's also a nice capability to allow. If anything, we tend
> > to err on the side of flexibility in ZF.
> >
>
> Implicit token scanning for each and every config string? That's not
> flexibility, that's madness :-)
>
> If you really need that for some Special Tactics [tm] , you could still
> do parsing with some component that will process those text files and
> then feed it to config listener.

I actually like the idea of having a component that pre-processes config
files to do the constant substitutions -- this would make the config
parsers themselves much simpler, simplify the formats (simply use the
constants where needed), and make it explicitly opt-in. Then, if folks
want to use the chdir() paradigm, they can simply _not_ use constants in
the config files.

Overall, I think this is a good direction to move in -- my earlier
reservations were primarily due to forgetting that
fopen/file_get_contents/etc. resolved based on CWD. My only other
reservation is simply a matter of taste: I foresee a potential explosion
of configuration files. Additionally, it makes the need for config
"imports" much more immediate.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Gregory
Tokens/References/Constants within the config files will most likely
be needed for the DI config anyway? e.g referring to other
variables/objects.

Doing the chdir does seem nice, even though it may make path
declarations a little more dense in some places. However, having
stepped through changing the code respectively, again raised the
concern:

<?php

  include /app1/init.php
  include /app2/init.php

  $app1 = ....

  $app2 = ...

  $results = $app1->getSomething();

  $app2->doSomething($results);


But we've just implicitly changed the cwd for $app1.


But my thinking/implementation maybe incorrect.

--
Greg

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

weierophinney
Administrator
-- Greg <[hidden email]> wrote
(on Tuesday, 06 December 2011, 02:23 PM -0600):
> Tokens/References/Constants within the config files will most likely
> be needed for the DI config anyway? e.g referring to other
> variables/objects.

You can always substitute the constant/token _values_ in the
configuration files. Also, note that if such behavior is desired, we'd
offer an opt-in pre-parser that would push in the values.

> Doing the chdir does seem nice, even though it may make path
> declarations a little more dense in some places. However, having
> stepped through changing the code respectively, again raised the
> concern:
>
> <?php
>
>   include /app1/init.php
>   include /app2/init.php
>
>   $app1 = ....
>
>   $app2 = ...
>
>   $results = $app1->getSomething();
>
>   $app2->doSomething($results);
>
>
> But we've just implicitly changed the cwd for $app1.
>
> But my thinking/implementation maybe incorrect.

I'm actually not certain what you're getting at in the above example --
do the init.php files do the chdir() and instantiate an Application
object? If so, I'd consider that an edge case -- it's unlikely you'd
want to intermingle two _application_ instances. And, if you did, you'd
be aware that you'd need to do so environment munging -- this is even
true when using constants.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Artur Bodera
In reply to this post by weierophinney
On Tue, Dec 6, 2011 at 8:17 PM, Matthew Weier O'Phinney <[hidden email]>wrote:

> I actually like the idea of having a component that pre-processes config
> files to do the constant substitutions -- this would make the config
> parsers themselves much simpler, simplify the formats (simply use the
> constants where needed), and make it explicitly opt-in. Then, if folks
> want to use the chdir() paradigm, they can simply _not_ use constants in
> the config files.
>

The best place for this is IMHO Zend\Config\* (along with config merging).
It already supports multiple formats and token parsing mechanisms could
be implemented as a decorator or "processor".

For example:

$config = new Zend\Config\Json(file_get_contents('config.json'));
$tokenParser = new Zend\Config\Parser\Token();

// Walk recursively through all values in config and
// replace all tokens with values
$tokenParser->parse($config,array(
    'FOO' => 'something',
    'BAR' => 'something else'
));

Another example using defined PHP constants:
$config = new Zend\Config\Json(file_get_contents('config.json'));
$tokenParser = new Zend\Config\Parser\Constant();

// Walk recursively through all values in config and
// replace any tokens from get_defined_constants() with values
$tokenParser->parse($config);

Parsing only one selected branch would be trivial:
$tokenParser->parse($config->modules->foomodule);


Internally parser's just a RecursiveIterator walking through Config
structure :)

Would that satisfy your use cases?

A.

--
      __
     /.)\   +48 695 600 936
     \(./   [hidden email]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

weierophinney
Administrator
-- Artur Bodera <[hidden email]> wrote
(on Tuesday, 06 December 2011, 10:19 PM +0100):

> On Tue, Dec 6, 2011 at 8:17 PM, Matthew Weier O'Phinney <[hidden email]>wrote:
> > I actually like the idea of having a component that pre-processes config
> > files to do the constant substitutions -- this would make the config
> > parsers themselves much simpler, simplify the formats (simply use the
> > constants where needed), and make it explicitly opt-in. Then, if folks
> > want to use the chdir() paradigm, they can simply _not_ use constants in
> > the config files.
>
> The best place for this is IMHO Zend\Config\* (along with config merging).
> It already supports multiple formats and token parsing mechanisms could
> be implemented as a decorator or "processor".
>
> For example:
>
> $config = new Zend\Config\Json(file_get_contents('config.json'));
> $tokenParser = new Zend\Config\Parser\Token();
>
> // Walk recursively through all values in config and
> // replace all tokens with values
> $tokenParser->parse($config,array(
>     'FOO' => 'something',
>     'BAR' => 'something else'
> ));
>
> Another example using defined PHP constants:
> $config = new Zend\Config\Json(file_get_contents('config.json'));
> $tokenParser = new Zend\Config\Parser\Constant();
>
> // Walk recursively through all values in config and
> // replace any tokens from get_defined_constants() with values
> $tokenParser->parse($config);
>
> Parsing only one selected branch would be trivial:
> $tokenParser->parse($config->modules->foomodule);
>
> Internally parser's just a RecursiveIterator walking through Config
> structure :)
>
> Would that satisfy your use cases?

Absolutely. And, honestly, it doesn't even need to parse the structure;
it can do simple string replacements on text, in-memory, prior to
feeding to the format parser. :)

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Gregory
In reply to this post by weierophinney
On Tue, Dec 6, 2011 at 3:05 PM, Matthew Weier O'Phinney
<[hidden email]> wrote:
>>
>> But my thinking/implementation maybe incorrect.
>
> I'm actually not certain what you're getting at in the above example --
> do the init.php files do the chdir() and instantiate an Application
> object? If so, I'd consider that an edge case -- it's unlikely you'd
> want to intermingle two _application_ instances. And, if you did, you'd
> be aware that you'd need to do so environment munging -- this is even
> true when using constants.

You're right, I wasn't thinking clearly on that.

The only constant I use in the config is the environment. Any others
which are about the directory paths really can/should be refactorable.

Its still a little scary though (naturally), we've been so used to
moving towards being explicit in the file paths because it removes any
headaches, what happens if you need to bootstrap inside a third party
app thats in the /public dir. Anyhow, thats just me.


--
Greg

--
List: [hidden email]
Info: http://framework.zend.com/archives
Unsubscribe: [hidden email]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: ZF2 usage of constants in configs

Artur Bodera
On Wed, Dec 7, 2011 at 12:09 AM, Greg <[hidden email]> wrote:

> Its still a little scary though (naturally), we've been so used to
> moving towards being explicit in the file paths because it removes any
> headaches, what happens if you need to bootstrap inside a third party
> app thats in the /public dir. Anyhow, thats just me.


Does that other app rely on chdir() ?

If it does, it will most likely also need to chdir() inside the same app
root.

If it doesn't (i.e zf1 app), then it won't mind that change because it uses
abs paths everywhere.


--
      __
     /.)\   +48 695 600 936
     \(./   [hidden email]
Loading...