views:

81

answers:

1

If I remember correctly, parsing .ini files in PHP takes a long time. So, why not cache it (the file won't change during a request)

What is the best way to do this?

Or are there any reasons not to do it?

+3  A: 

I also cache my application.ini Like you said, loading .ini files take a long time.

Make sure you have the following directory (your cache dir): /application/data/cache

I extend Zend_Application with My_Application, see code:

<?php
require_once 'Zend/Application.php';

class My_Application extends Zend_Application
{

    /**
     * Flag used when determining if we should cache our configuration.
     */
    protected $_cacheConfig = false;

    /**
     * Our default options which will use File caching
     */
    protected $_cacheOptions = array(
        'frontendType' => 'File',
        'backendType' => 'File',
        'frontendOptions' => array(),
        'backendOptions' => array()
    );

    /**
     * Constructor
     *
     * Initialize application. Potentially initializes include_paths, PHP
     * settings, and bootstrap class.
     *
     * When $options is an array with a key of configFile, this will tell the
     * class to cache the configuration using the default options or cacheOptions
     * passed in.
     *
     * @param  string                   $environment
     * @param  string|array|Zend_Config $options String path to configuration file, or array/Zend_Config of configuration options
     * @throws Zend_Application_Exception When invalid options are provided
     * @return void
     */
    public function __construct($environment, $options = null)
    {
        if (is_array($options) && isset($options['configFile'])) {
            $this->_cacheConfig = true;

            // First, let's check to see if there are any cache options
            if (isset($options['cacheOptions']))
                $this->_cacheOptions =
                    array_merge($this->_cacheOptions, $options['cacheOptions']);

            $options = $options['configFile'];
        }
        parent::__construct($environment, $options);
    }

    /**
     * Load configuration file of options.
     *
     * Optionally will cache the configuration.
     *
     * @param  string $file
     * @throws Zend_Application_Exception When invalid configuration file is provided
     * @return array
     */
    protected function _loadConfig($file)
    {
        if (!$this->_cacheConfig)
            return parent::_loadConfig($file);

        require_once 'Zend/Cache.php';
        $cache = Zend_Cache::factory(
            $this->_cacheOptions['frontendType'],
            $this->_cacheOptions['backendType'],
            array_merge(array( // Frontend Default Options
                'master_file' => $file,
                'automatic_serialization' => true
            ), $this->_cacheOptions['frontendOptions']),
            array_merge(array( // Backend Default Options
                'cache_dir' => APPLICATION_PATH . '/data/cache'
            ), $this->_cacheOptions['backendOptions'])
        );

        $config = $cache->load('Zend_Application_Config');
        if (!$config) {
            $config = parent::_loadConfig($file);
            $cache->save($config, 'Zend_Application_Config');
        }

        return $config;
    }
}

And I change my index.php (in the public root) to:

<?php

// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
    realpath(APPLICATION_PATH . '/../library'),
    get_include_path(),
)));

/** My_Application */
require_once 'My/Application.php';

// Create application, bootstrap, and run
$application = new My_Application(
    APPLICATION_ENV,
    array(
            'configFile' => APPLICATION_PATH . '/configs/application.ini'
    )
);
$application->bootstrap()
            ->run();

Reload the page and you see the ini file cached. Good luck.

Enrico Pallazzo
What is the performance increase when the application.ini is cached? Do you have benchmarks for this?
Jurian Sluiman