I'm not really sure what the best way to use global configuration options.
For example, if when a file is uploaded I want to move it in the correct folder.
I can hardcode the path, but it's not really the best thing.
I can use a CONSTANT
I can use config.ini and sets some common config options. Maybe then register a config object in Registry
How do you do? Any advice?
A Zend_Config object in the Registry is the usual method that ZF follows here. Many of the ZF classes can accept Configs, and there's pretty much no better way to deal with it within ZF.
(Just remember, the Registry pattern is little more than a glorified global anyway.)
Create a config.ini, and within it separate your configurations like so:
[development]
;File Upload settings
FileUpload.path = /some/path
[production]
;File Upload settings
FileUpload.path = /production/path
Now somewhere in your Bootstrap.php, you can do this:
$config = new Zend_Config_Ini(
self::$root . '/config/config.ini',
'development'
);
self::$registry->configuration = $config;
And in any controller:
$config = Zend_Registry::get('configuration');
echo $config->FileUpload->path;
I use Zend_Registry::set('foo', '/path/to/correct/folder') once, and then call it whenever I need it with Zend_Registry::get('foo') anytime I need it. Works great!
Related
Say I want a constant, a function or a class to be available in all my models, views and controllers code (within a particular web site (application)). Where can I put them? I don't mind importing them explicitly in every file I need them in but I don't know how (simple require_once does not seem to work).
You can put them in the vendor folder (in application/vendor or modules/MOD/vendor). Then you can load it like this:
require Kohana::find_file('vendor', 'folder/file','ext');
You can read up more on this in the user guide
Now, it should be stated you should in general not use functions or globals.
I declare Constants in Bootstrap.php and create my own Helpers for general functions under application/classes/Helpers.
If you need to integrate a third party library into Kohana or want to make code available to other Kohana users consider creating a module instead.
You can define all your constants in new php file and place it in the application/classes directory. In your Template controller or in the main controller like Welcome or Website, just place the code in the __constructor()
require_once Kohana::find_file( 'classes', 'filename' );
I suggest you to put your constant variables in the bootstrap.php file because this is loaded by the framework before every request.
You can simply put your classes in the root of the classes directory, the framework will find.
This worked well for me...
In application/config/constants.php:
define('SOME_COOL_CONSTANT', 'foo');
return array();
In index.php:
Kohana::$config->load('constants');
SOME_COOL_CONSTANT should then be available globally.
I'm modifying a website and I would like to add a config file for it so that when when moving the website to another server, I only need to change environment parameters like database information only once. But I don't know how to apply the config file for the whole site. I tried to use include_once() and make it global using keyword global but it only works in the current file. If I don't use define() to make these parameters as constant, are there any other way to achieve this? Thank you.
You can create a class Config and store your config parameters as Class Constants. Then include this class everywhere you need it, or use Autoload it.
class Config {
const databaseUsername = "user123";
const databasePassword = "pass456";
}
echo Config::databaseUsername;
echo Config::databasePassword;
But as in my experience, define() works perfectly well, unless you need to store more complicated data types (arrays for example).
To avoid include the config file everywhere, you could set auto_prepend_file in your PHP.ini, but I personally find this solution obscure, since it's not obvious for another developer working on your code that a PHP file is auto-included.
I'm using the default Zend_Application design pattern which loads a zend config ini file automatically in the application bootstrap and I need to ini file's variables across many models and controllers.
Right now, I'm solving it by settings the config object as a key into Zend_Registry:
protected function _initConfig()
{
$config = new Zend_Config($this->getOptions());
Zend_Registry::set('config', $config);
}
Generally, I don't like using Zend_Registry, as it doesn't offer code auto complete in my IDE, and it's hard to keep track on what I have in the registry namespace.
Is there another way to access the Zend_Application's config ini?
In a controller you should be able to do:
$this->getInvokeArg('bootstrap')->getOptions();
to access the config. For models you really should be passing in the options you need. Otherwise your only choice is really the registry.
You could always initialise it as needed yourself with
$options = new Zend_Config_Ini('/path/to/config.ini',
'config');
Wich is pretty much what the bootstrap does for you. Then you would have autocomplete on $options. But you would have to initialise it everytime you need it.
I think modifying your code to suit autocomplete is not the greatest idea ever. But this is personnal.
If I am not mistaken with Zend Studio 8/9 (maybe 7) you DO have autocomplete even for objects returned by Zend_Registry::get().
this is more a conceptual question. Consider you have a php framework that runs a generic website.
You can of course tweak the framework behavior with settings, the question is: where is more natural to place these settings?
My framework consists of some functions that helps me doing some tasks (for example cache managment).
In this fw I use a generic variable
$config = array( 'setting1'=>'value1' etc );
And if a function needs it does a global:
function manageCache() {
global $config;
//> perform task with settings from $config
}
Consider the procedural nature of my framework, and the fact someone says global is evil, how would you manage the settings?
Thanks
Edit1: Please don't tell to use constats, i have tons of settings and i don't want to make a tons of constant + they must be editable
There's nothing wrong with your configuration array. It's quite a common approach. The fallacy globals are evil is cargo cult programming advise. Please ignore.
Now the $config array is often easy to use by itself. But you can expand on that. It's quite simple for example to turn it into an ArrayObject once initialized:
$config = new ArrayObject($config, 2);
This will allow you to access the settings as $config["setting"] and $config->setting alike. It's easier on the eyes.
If you also want to avoid having to import the array everywhere, because you sometimes need just a single value, then expand with a wrapper function config("setting") for convenience.
Btw, I'm usually using a mix of config array and constants myself. And I made a little management tool for plugins and a settings array in a central config.php. http://web135.srv3.sysproserver.de/milki.erphesfurt.de./genericplugins/genconfig.html
If your settings are constant and do not change then consider using define() - http://php.net/manual/en/function.define.php
//Set anywhere like this
define("DB_NAME", "stackoverflow");
// You can then read it from anywhere using
echo DB_NAME;
Is they need to be editable then you can use globals, but ensure that register_globals is off.
If you are using PHP5 then you could implement the Registry pattern to do this.
I'd be tempted to use a define rather than a variable, as this would at least remove the need for global variables.
That said, you can't (easily) store complex data types such as arrays via defines, so you'll want to factor this in.
Pass the global as a parameter of function
manageCache($config);
Globals are really evil
Normally you would have a config folder somewhere in your framework that you auto include on startup.
It would potentially look like this:
ROOT/
config/
db.php
cache.php
constants.php
You would then have something like a Config class that handles importing this configuration variables and converting them into instance variables. This way you can access these configuration variables like this:
$config->get_config('settings_1');
Just need get some vals located in application.ini(main ini) in the Controller plugin
I know I can create an instance of Zend_config_Ini but would like to use the existing resource (application.ini is already used in Front Controller)
Use Zend Registry
// when loading the config
Zend_Registry::set('config', $config);
// later, somewhere
$config = Zend_Registry::get('config');
Try:
Zend_Controller_Front::getInstance()->getParam('bootstrap')->getOptions();
If you now that you will need your configuration values from application.ini in few places around your whole application, you could read it up in bootstrap and store it in registry:
$appConfig = new Zend_Config_Ini('path/to/application.ini');
Zend_Registry::set('applicationConfig', $appConfig);
then later you can always access it:
Zend_Registry::get('applicationConfig')->someValue;
For reasons of testability and decoupling I would not use the Zend_Registry approach. In my opinion the plugin should not know anything about Zend_Config, but instead all options that are needed in the plugin should be injected from outside.
For example, if you want to use the config option "MyOption" in the Plugin Controller_Plugin_MyPlugin you could inject the needed parameters in the Bootstrap class as follows:
public function run()
{
$sopPlugin = $this->getResource('frontcontroller')->getPlugin('Controller_Plugin_MyPlugin');
$sopPlugin->setMyOption($this->getOption('MyOption'));
parent::run();
}
The advantage is that with this solution you avoid dependencies to Zend_Registry (which in fact is just an euphemism for a global variable) in your plugin code.