Storing Global Configuration Values

The final piece we will implement in our super secret Ninja class, Globals.php is a way to store global configuration items. Things like directory names, database credentials, or really anything that you don't want to hard-code into your application. Those are the things that you want in your Globals.php so you don't have to remember where they are or how to access them.

Another reason you don't want to hard-code these items is that in most large scale applications, we have multiple environments. Development, Staging, QA and production; each of these may have slightly different variations of things like directory names or database credentials. You want to be able to deploy your codebase once and just monkey with the config file.

You could, without any further changes, add all your properties to Globals.php as "static public", hard code their values into the class and be done with it. I'll tell you from experience, as your Globals.php class grows and your team grows, managing your Globals.php will become a pain. Not only do you have people adding code into it as your needs grow but since each environment can be different, (and thus the values can be different), you end up with a mess. The easiest way to deal with a mess like this is to use Zend_Config to store all of your values. This allows us to only have code in the Globals.php and still use it to manage our global parameters.

Out of the box Zend_Config comes with adapters to handle config data stored in INI or XML files via Zend_Config_Ini or Zend_Config_Xml. Additionally, you can store data in a native PHP file as an array. If you choose to do this then you use the Zend_Config class to load it in.

Now I'm partial to INI files so we are going to use the Zend_Config_Ini class. However, the concepts we discuss here can easily be translated to use Zend_Config_Xml. Zend_Config_Ini supports the commonly accepted INI file format:

[header]

key1=value1 key2=value2 key3=value3 subhead.key1=value4 subhead.key2=value5 subhead.key3=value6

If you load Zend_Config_Ini passing in the "header" parameter then you would get key1=value1.

$config = new Zend_Config_Ini('/path/to/config.ini', 'header');

echo $config->key1; // will print "value1"

echo $config->subhead->key1; // will print "value 4"

Additionally, the INI file format supports inheritance.

[header]

key1=value1 key2=value2 key3=value3 subhead.key1=value4 subhead.key2=value5 subhead.key3=value6

[header2 : header] key1=value7 key2=value8 key3=value9

$config = new Zend_Config_Ini('/path/to/config.ini', 'header2'); echo $config->key1; // will print "value7"

This is useful when the same config file can be used for say, production and staging. However, if you are deploying the application to three different developers workstations, each of them will have their own ideas about how the directory structure above the application should be. They could also be on different operating systems, this would cause them to be very different. You could, of course set special headers for each and every environment you are deploying to; production, development, dev-matthew, dev-elizabeth, etc. However, as people come and go, you will find that very cumbersome. I've found that the easiest way to keep things clean is to have an overall INI for production and staging and allow each developer to create his or her own INI for their development environment. Doing so solves many problems and keeps decrees from "on high" as to how systems are to be laid out to a minimum.

Let's dive back into the code. The first thing we need to do is modify our Globals.php to manage the Zend_Config class. Add this line near the top of Globals.php with the other loaders.

Zend_Loader::loadClass('Zend_Config_Ini');

Next, we need a place to put our instance of Zend_Config_Ini so we don't have to keep recreating it.

private static $_db = null; private static $_cache = null; private static $_config = null;

Finally, and by now, you should be able to do this one on your own, we need to put the getConfig() function in.

public static function getConfig() {

if (self::$_config != null) { return self::$_config;

self::$_config = new Zend_Config_Ini(

dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.ini', null);

return self::$_config;

Zend_Config_Ini takes 3 parameters: • File Name of the INI file

• The of the section to load. In this case, we passed in NULL so that all sections would be loaded. If we had a segmented INI file, we could have passed in a string with the name of the section to load or an array of strings that correspond to multiple sections in the INI file.

• Optionally, we can pass in either true or false to answer the question, allow the program to modify the values. The default is false and since in our example, we don't want to allow the program to make changes, we don't override it.

The file name we pass in is:

dirname(__FILE__) . DIRECTORY-SEPARATOR . 'config.ini'

If you understand this then skip this little paragraph. If not, here's what that resolves to. At some point we have to make an assumption to get our bootstrap going. Just as we assume the bootstrap file will be named index.php, we will assume that the config file is named config.ini and it's in the same directory as Globals.php. These are safe assumptions for most of us, however if you ever want to change that, you'll have to figure out where to put it on your own and modify this line. So the dirname(__FILE__) resolves to the full path and directory name that Globals.php is located in. DIRECTORY_SEPARATOR is a PHP constant that holds the appropriate value to separate directories on the OS you are working on. (\ for windows, / for Linux and OSX.) Feel free to hard-code this but if you ever deploy on another OS, you may have problems. I always find it's best to stick with the constant.

The rest, you've seen before. So, now that we can use a config.ini, we need to actually make one. For our sample, let's use this one:

title = "Keyword Content Analyzer" db.host = "localhost" db.username = "example" db.password = "example" db.dbname = "example3" dirs.cache = "c:\web\htdocs\cache"

There is no secret naming convention that has to be followed. In this case, I used the names of the parameters I will be filling.

This now gives us a good working base for our example. Feel free to parameterize any other properties in the example you wish. The above is the contents of the config.ini in the example code.

Now, let's implement it. Where shall we begin? How about in Globals.php itself? That's where most of the values are hard coded anyhow. Let's start with the database.

static public function getDBConnection() {

self::$_db = Zend_Db::factory('Pdo_Mysql', array ('host' => self::getConfig()->db->host, getConfig()->db->username, getConfig()->db->password, getConfig()->db->dbname));

'username' => self 'password' => self 'dbname' => self Zend_Db_Table::setDefaultAdapter(self::$_db); return self: : $_db;

It's just that easy. Since we are storing the instance of Zend_Config_Ini the first time we call getConfig() there is no performance penalty to making multiple calls. Now, let's update our getCache():

static public function getCache() {

self::$_cache = Zend_Cache::factory( 'Core', 'File', array('lifeTime'=>600,

'automatic_serialization'=>true), array('cache_dir'=>self::getConfig()->dirs->cache));

return self::$_cache;

As you can see, we could have easily parameterized everything in the cache, but really, for our example, the only thing that is going to be a pain for you is the cache directory. This is only because, you may not put all your projects under c:\web like I do. Now you can move things around to suit your development style.

Beyond the Globals.php, there is one other place we can use our new config toy. The first parameter we stored is the title of the application. Right now it appears in all of the template files. Let's change it in index.phtml.

Open view\scripts\index\index.php and find the <title> tag. Change it to this:

<title><?PHP echo Globals::getConfig()->title;?></title>

Save it and refresh your browser. Didn't change at all did it? Great! Now, go edit your config.ini. Put your name in there for all to see. Something like:

title = "Cal's Keyword Content Analyzer"

Now save the config.ini and refresh the browser. You should now see a change. See isn't it fun when things work?

Going back to the line we changed in index.phtml, you should have noticed that unlike the changes to Globals.php, this time we used Globals::getConfig() instead of self::getConfig(). That's the only difference. Anytime you want to make a call outside of Globals.php itself you have to use the static class name.

Was this article helpful?

0 0

Post a comment