Skip to content

Instantly share code, notes, and snippets.

@Thinkscape
Created December 1, 2011 09:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Thinkscape/1415354 to your computer and use it in GitHub Desktop.
Save Thinkscape/1415354 to your computer and use it in GitHub Desktop.
Discussion on usage of constants in ZF2 application configuration
[19:22] <EvanDotPro> :) no rush
[19:27] <Thinkscape> So ... I feel like in this discussion on using constants inside config files, there are literaly 2 constants we're talking about: APPLICATION_ENV and APPLICATION_PATH. These are most important ones.
[19:28] <Thinkscape> But.... with recent changes in ZF2 core, APPLICATION_ENV is reflected with different config files being loaded --- so it's irrelevant
[19:28] <Thinkscape> APPLICATION_PATH on the other hand does not make any sense, as we do not use application path...
[19:28] <Thinkscape> there is no application/ dir per se, as modules go into modules/, vendor into vendor/ and config into config/
[19:29] <Thinkscape> So by definition --- path definitions should be >RELATIVE<
[19:29] <Thinkscape> For example: modules.somemodulewithsqlite.sqlite.params.file = "data/db.sqlite"
[19:29] <Thinkscape> Which means: ./data/db.sqlite
[19:29] <Thinkscape> Absolute paths should be prepended with a slash:
[19:30] <Thinkscape> modules.somemodulewithsqlite.sqlite.params.file = "/var/lib/myapp/data/db.sqlite"
[19:30] <Thinkscape> The only caveat is with CLI purposes, where ZF2 app could be invoked from another dir... but no problem with that --- cli.php could just do <?php chdir(__DIR__);
[19:31] <Thinkscape> (and all relative paths make sense again)
[19:35] * Thinkscape hears crickets...
[19:36] <EvanDotPro> Thinkscape: sorry, dealing with some work things right now too, standby :)
[19:42] <Thinkscape> ... like you, Evan were the only person using configuration with zf :-)
[19:42] <EvanDotPro> heh
[19:42] <EvanDotPro> okay so you're right paths should be relative
[19:43] <Thinkscape> But it's ok... I believe someone here will eventually switch to that irc window and see it ... or not.
[19:43] <EvanDotPro> the problem is we have nothing to make them relative TO
[19:43] <Thinkscape> we have
[19:43] <EvanDotPro> from within a module's config file, how do you point to that views directory in that same module?
[19:48] <Thinkscape> This is path resolving
[19:49] <Thinkscape> but not OS path resolving, but context-related resolving...
[19:49] <Thinkscape> Like the recent Zend\View\Templateresolver and TemplatePathStack thingies...
[19:50] <Thinkscape> This is how you resolve a relative blob, like "index/index" into "/var/foo/bar/application/views/scripts/index/index.phtml"
[19:50] <Thinkscape> So what you're asking should be considered at the level of that particular case (context)
[19:50] <Thinkscape> For example view rendering.
[19:52] <Thinkscape> Inside a module, you can perform resolving using __DIR__, which will be most accurate (given a module can live in a directory named anything).
[19:52] <Thinkscape> Inside a config, you are defining things explicitly ... user is doing that.
[19:52] <Thinkscape> So he/she knows exactly if that given file sits in vendor/foo/file.png or vendor/bar/file.png
[19:53] <Thinkscape> But I can't think of many examples where you'd need to use that level of path granularity inside a config file...
[19:55] <EvanDotPro> we already have several in the skeleton
[19:55] <EvanDotPro> adding view paths is the most obvious
[20:00] <Thinkscape> If you need to define a non-standard view path, then you know that path ...
[20:00] <Thinkscape> so you can just type it in into config .... i.e. "./vendor/foo/views"
[20:01] <Thinkscape> If you (for some reason) keep it outside, you put in an abs. path "/var/www/html/otherproject/vendor/foo/views"
[20:01] <Thinkscape> Configuration is performed manually. If you want to automatically register view paths for a module, you will do it inside module.php, and you can inject it with function call (with __DIR__ ."/views" or something)
[20:04] <EvanDotPro> hmmm, maybe that's the answer.. anything that needs to automatically use relative paths has to do so manually in event listeners?
[20:04] <EvanDotPro> it would avoid the whole config format problem, so people could use inis and crap again immediately.
[20:05] <EvanDotPro> i dunno
[20:05] <EvanDotPro> people are already complaining about boilerplate code though
[20:05] <Thinkscape> I'm amongs them
[20:05] <Thinkscape> Drupal does it
[20:05] <Thinkscape> wordpress too
[20:06] <Thinkscape> in wordpress index.php is the entry point for main page... all modules just use relative paths
[20:06] <Thinkscape> it's path-proof this way. OS handles the rest.
[20:07] <Thinkscape> If you really really need absolute path, you just put it in, and it will resolve accordingly. I stopped having problems with paths since php 4.0.0 :P
[20:09] <Thinkscape> EvanDotPro: I don't see many use cases here. I'm quite comfortable with going case by case and resolving these. View script paths are easy to handle. It's semi-standarized, it's resolved inside MVC anyways ... so no need to have constants or absolute paths.
[20:09] <Thinkscape> Do you see any other valid use cases for concating paths inside configs ?
[20:10] <EvanDotPro> there's no such thing as relative from modules to index.php though
[20:10] <EvanDotPro> because people wnat to be able to put modules anywhere
[20:10] <Thinkscape> explain
[20:11] <Thinkscape> I mean - I know that modules can be mini-apps by themselves.... but it's magic
[20:11] <Thinkscape> magic that will be coded inside module.php
[20:11] <Thinkscape> What if a module A wants to use a file from module B ???
[20:11] <EvanDotPro> /usr/share/php/zfmodules/* and /var/www/vhosts/myproject.com/vendor/*
[20:11] <Thinkscape> It will query ModuleManager, try to find module B and resolve its path and perform that operation.... it has nothing to do with configs
[20:12] <Thinkscape> In your example, using APPLICATION_PATH is even harmful...
[20:12] <Mage_Dude> I imagine that EpdUser will be in usr/share for all zf apps to use but each app will also have other modules but they all share the user module. Sound about right?
[20:13] <Thinkscape> if application lives inside /var/www/vhosts/myproject.com and uses module in /usr/share/php/zfmodules/ then it's up to module author to decide if it wants a file from the first path or the second one.
[20:14] <Thinkscape> Mage_Dude: that's a valid use case... but it's up to the module to select which view scripts to use.
[20:14] <Thinkscape> (or use priority stack so local app view scripts come before /usr/share/module/edpuser/views)
[20:14] <EvanDotPro> Mage_Dude: if that's what you want, sure
[20:14] <EvanDotPro> Mage_Dude: it'll be totally up to you
[20:15] <EvanDotPro> like if i totally re-wrote EdpUser for v1.0, then you could have v0.2.0 for some "legacy" app locally, then 1.0 in your /usr/share/module/*
[20:15] <EvanDotPro> or whatever you want really
[20:16] <EvanDotPro> Thinkscape: view scripts are resolved by the priority stack, yes.
[20:16] <Thinkscape> EvanDotPro: do you see how it's coming together ? :)
[20:17] <EvanDotPro> i don't see how the problem would be solved really. you'd still just be doing it yourself in php instead of a config file
[20:17] <EvanDotPro> which will make more people complain about boilerplate
[20:18] <Thinkscape> which problem?
[20:18] <Thinkscape> let's try again: give me an example of absolute path usage inside a user-edited config
[20:42] <EvanDotPro> Thinkscape: https://github.com/EvanDotPro/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php#L17
[20:43] <EvanDotPro> Thinkscape: https://github.com/EvanDotPro/EdpUser/blob/master/config/module.config.php#L84
[20:46] <Thinkscape> I regard is a weak design
[20:47] <Thinkscape> There's not a lot of these though...
[20:49] <MikeA> Thinkscape: & EvanDotPro: Given the scenario under discussion, could a user interface for installing various Lego bricks (modules) cope?
[20:50] <MikeA> ...a user interface like, say, the WordPress installer?
[20:50] <Thinkscape> we'll get there
[20:51] <EvanDotPro> MikeA: i see no reason that wouldn't be possible eventually
[20:51] <Thinkscape> backed with pyrus
[20:51] <EvanDotPro> right now we're laying the ground work for such a thing though
[20:51] <EvanDotPro> i think certain complex modules may always require some manual developer intervention
[20:52] <MikeA> EvanDotPro: Appreciated -- my point being that anything requiring a developer to hard-wire paths would surely break such a possibility.
[20:53] <EvanDotPro> well what i was saying was the _module_ developer would be wiring the paths relative to his module
[20:53] <EvanDotPro> well, i wasn't suggesting that, i was moreso clarifying what Thinkscape said.
[20:57] <MikeA> k -- hope you don't mind me asking from a real-world perspective because such matters lead to other issues...
[20:58] <MikeA> ...like mandatory registration of developer, version et al in module.config
[20:59] <EvanDotPro> well there will be certain required metadata for the feeds/repository
[20:59] <EvanDotPro> like version, etc
[20:59] <MikeA> :)
[20:59] <EvanDotPro> the community will come up with license/registration rules as a whole
[20:59] <EvanDotPro> i put up a wiki page and a ML thread
[20:59] <EvanDotPro> but no one has responded at all, really.
[21:00] <MikeA> EvanDotPro: on a separate matter, I like to assist with your module efforts (more from an admin perspective) -- if you want
[21:01] <EvanDotPro> which efforts?
[21:01] <MikeA> EvanDotPro: Well, about 3 years ago I began putting together a store in a project I called ModJewelz...
[21:02] <EvanDotPro> oh you want to help with the e-commerce project?
[21:02] <MikeA> EvanDotPro: ... figured I could act as some sort of librarian/coordinator -- and at times my two braincells cooperate, perhaps add a module or two
[21:04] <MikeA> http://modules.zendframework.com/#modules
[21:06] <MikeA> ...also http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+modules.zendframework.com
[21:13] <Thinkscape> "librarian" hehe
[21:14] <MikeA> :)
[21:16] <MikeA> Took me a couple of years to put together philosophies for key and common modular plugins to avoid the kind of mish-mash found in Drupal and WordPress...
[21:16] <MikeA> ...thought that mindset could bump into a useful role
[21:19] <Thinkscape> MikeA: well.. if it blends
[21:19] <Thinkscape> Whatever you say about that mess in drupal mod. repository... it simply works.
[21:19] <MikeA> yup
[21:19] <Thinkscape> There is a module for everything
[21:19] <Thinkscape> and they are drop-in ...
[21:20] <Thinkscape> so they save time, which is their main purpose.
[21:20] <MikeA> Hellish to identify one from the many though
[21:20] <Thinkscape> Otherwise - i'd write it myself... and notice one more thing... with thousands of those drupal mods, there is little overlapping.
[21:20] <Thinkscape> I disagree...
[21:20] <Thinkscape> for example: something vague as contact form or mail module
[21:20] <Thinkscape> there is like 3-5 of these
[21:21] <Thinkscape> you quickly filter those unmaintained for years
[21:21] * EvanDotPro is going to add BrowserID support to EdpUser
[21:21] <Thinkscape> and you are left with 2
[21:21] <Thinkscape> What is browserid ?
[21:22] <Thinkscape> ah, ok... another openid/openauth/me-too clone
[21:23] <EvanDotPro> exactly
[21:25] <DASPRiD> Thinkscape, thought about a replacement for constants?
[21:25] <Thinkscape> yup
[21:25] <Thinkscape> Above...
[21:25] <Thinkscape> I'll put it on pastebin
[21:25] <DASPRiD> ah
[21:26] <DASPRiD> lemme read
[21:26] <DASPRiD> reading…
[21:27] <DASPRiD> i already spoitted a few problems, but lemme finnish reading first
[21:28] <Thinkscape> sure
[21:30] <DASPRiD> okay, let me ask a question, maybe the answer erases my problems
[21:31] <DASPRiD> you have a path in your config, defining the storage directory for caching, and according to you, this path is relative: how does zend\cache know what this path is relative to?
[21:32] <Bittarman> /whois Thinkscape
[21:32] <Bittarman> :P
[21:32] <DASPRiD> a scape to think in
[21:34] <Bittarman> DASPRiD, or that it is even relative :)
[21:34] <Bittarman> the default behaviour would for it to be relative to the document root.. but how does a module vendor know that all setups will be the same?
[21:34] <DASPRiD> Bittarman, heh, there are regex patterns to find out that it is relative :P
[21:34] <Bittarman> DASPRiD, then we shouldn't do it :)
[21:35] <DASPRiD> Bittarman, nah, zend\cache does not know about document root, modules or configs
[21:35] <DASPRiD> it just gets a path
[21:35] <Bittarman> DASPRiD, exactly
[21:35] <DASPRiD> and when it is relative, for zend\cache, it will be relative to the zend\cache\backend\file
[21:35] <Bittarman> no it wouldnt.
[21:35] <DASPRiD> are you sure?
[21:35] <Bittarman> its relative to the current working dir
[21:35] <Bittarman> yes
[21:36] <DASPRiD> well, CWD is not safe to rely on
[21:36] <Bittarman> unless Zend\Cache\Backend\File is apeshitcrazybonkers and prepends __DIR__ to it... which it most definatly should *not* be doing.
[21:36] <Bittarman> DASPRiD, by default, if you use a relative path, thats what will happen.
[21:36] <Thinkscape> DASPRiD: let me explain
[21:36] <DASPRiD> Thinkscape, sure
[21:36] <Thinkscape> The main path for an app (which is also true for wordpress and drupal) is THE path .... for example /var/www/html/mysite
[21:37] <Thinkscape> Of course index.php lives under public/index.php but it does chdir(__DIR__. '/..')
[21:37] <Thinkscape> so
[21:37] <DASPRiD> does it?
[21:37] <Thinkscape> everything is relative to your (current) app
[21:37] <Thinkscape> if you want to go absolute, you prepend "/"
[21:37] <Bittarman> Thinkscape, hell no.
[21:38] <Bittarman> libs should *NOT* go changing the cwd. EVER EVER EVER EVER EVER
[21:38] <Bittarman> and index.php living in public/index.php has nothing to do with it...
[21:38] <Bittarman> public is the document root..
[21:38] <Thinkscape> libs do not change directory
[21:39] <Bittarman> you just suggested the stock index.php should...
[21:39] <EvanDotPro> Bittarman: +1, and vendors should not assume anything about the environment other than the expectations of the Module class and paths within the module itself.
[21:39] <Thinkscape> public is resources root. public/../ is application root
[21:39] <Bittarman> Thinkscape, no.. public is DOCUMENT root
[21:39] <Thinkscape> what is a "document"
[21:39] <Thinkscape> ?
[21:39] <Bittarman> as in.. where the webserver should be configured to look for the root of the host.
[21:40] <Thinkscape> ah ok
[21:40] <Thinkscape> sure
[21:40] <Thinkscape> public is document root
[21:40] <Thinkscape> public/.. (simplification) is application root
[21:41] <Thinkscape> and is the main dir for all php scripts inside that application.
[21:41] <DASPRiD> except when the document root is somewhere else
[21:41] <Thinkscape> you can have document root wherever you want.
[21:41] <Thinkscape> Index.php need to know of course where it is
[21:41] <DASPRiD> to grasp the entire picture: EvanDotPro: which kind of paths would be specified in a module?
[21:41] <Thinkscape> but let's focus on modules, libraries, zend core etc.
[21:42] <Bittarman> so, the public dir is the cwd (usually)
[21:42] <Bittarman> relative paths in configs are no solution to anything.
[21:42] <Thinkscape> Bittarman: give some examples of non-relative paths in configs
[21:42] <Thinkscape> we'll go trough these
[21:42] <DASPRiD> Thinkscape, okay, here's an example
[21:43] <Bittarman> you can't assume that the cwd has not changed, and there is no way in hell that regex's should be used.. nor that vendors should be forced to check before using a path whether its relative or absolute
[21:43] <Bittarman> configs should have absolute paths, and that can only really be achieved with constant support.
[21:43] <DASPRiD> the main application defines a DATA_DIR constant pointing to a directory inside the application directory or even outside it. now a module could use that constant and say "my uploaded images get stored in DATA_DIR . '/module-name'"
[21:43] <DASPRiD> Thinkscape, how'd that be solved with relative paths only?
[21:44] <Thinkscape> DASPRiD: a data dir i something that should be injected with configuration
[21:44] <Thinkscape> not "figured out" using some magic super-global constants...
[21:44] <Thinkscape> DATA_DIR, why not DATA_PATH ?
[21:44] <Thinkscape> or ZF_DATA_FOLDER ?
[21:44] <DASPRiD> this is anything but magic
[21:45] <DASPRiD> how'd you solve that with injection?
[21:45] <Thinkscape> This part of the sentence is strange to me "the main application defines a DATA_DIR"
[21:45] <Thinkscape> why does the Zend\Application have to do this?
[21:45] <DASPRiD> there is no Zend\Application
[21:45] <Thinkscape> There is no spoon...
[21:45] <Thinkscape> :)
[21:45] <Bittarman> upload path
[21:45] <Thinkscape> You configure an upload path manually in your configuration
[21:46] <Bittarman> a common one for us.
[21:46] <DASPRiD> in which, Thinkscape, the application config or the moduel config?
[21:46] <Thinkscape> module.foobar.uploaddir = "data/uploads" <------ relative to main application dir
[21:46] <Thinkscape> or
[21:46] <Thinkscape> module.foobar.uploaddir = "/var/data/uploads" <------ absolute on that server
[21:46] <DASPRiD> Thinkscape, the module doesn ot know where the data directory is located
[21:46] <Thinkscape> It will know when you configure it
[21:46] <Thinkscape> explicitly
[21:46] <Thinkscape> not via magic static
[21:46] <Thinkscape> or discovery
[21:47] <DASPRiD> Thinkscape, so you say, having 10 moduels, and all modules have something to do with uploads, you have to copy paste the path to all module configs, and when changing the path, you have to update all those configs?
[21:48] <Thinkscape> DASPRiD: that is basically how you handle configuration from the bottom up
[21:48] <Thinkscape> you inject configuration (hence DiC) into modules
[21:48] <Thinkscape> not the other way around
[21:48] <Thinkscape> (modules fetching configuration from registry or global $config)
[21:48] <DASPRiD> Thinkscape, okay, another example
[21:49] <DASPRiD> a module brings additional figlet fonts with, zend\text\figlet expects absolute paths for sure, how would the configuration value for the font path look like?
[21:50] <DASPRiD> mh, nevermind, the user configures it…
[21:50] <Thinkscape> If I twist your sentence around I get: I have 10 modules and each of them figures upload path automatically (?)
[21:50] <Thinkscape> Yeah user gives that data
[21:50] <Thinkscape> or
[21:50] <Thinkscape> module.php::init() contains some magic auto-discovery of fonts
[21:51] <Thinkscape> for example: you have a hub module (figlet) and 10 modules with fonts (fontA, fontB, fontC) .... then the hub module is configured with a path for all fonts: modules.figlet.fontpath = "data/fonts".
[21:51] <Thinkscape> Then all child modules containing fonts will have something like: module.php <? function init(){ $fontPath = modulemanager::getModuleConfig('figlet')->fontpath; .. register another path ....
[21:52] <Thinkscape> or a better way:
[21:53] <Thinkscape> figlet module listens to a modulemanager or application event called "register.figlet.font" ---- each child module fires that event with the path to new font. The parent figlet module now contains a stack of all installed fonts.
[21:53] <DASPRiD> ic…
[21:53] <DASPRiD> EvanDotPro, ping
[21:57] <DASPRiD> Thinkscape, okay, I think I can't spot any problems there
[22:00] <DASPRiD> Thinkscape, could you sumarize that in email and send it to the contributors mailing list, so other people have a change to give feedback on that?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment