Yii Framework Forum: Configuration files in Yaml - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Configuration files in Yaml A more readable way to maintain Yii settings (easy installation) Rate Topic: ***** 2 Votes

#1 User is offline   stefanos 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 09-February 11

Posted 30 March 2011 - 08:50 PM

The border detection of arrays and subarrays in a php configuration file is a real headache to me. Especially when pretty coding is not in the top priorities, which is the case for the most of the time.

I met Yaml in Ruby on Rails config files and I really appreciated when I was first encountered the Yii's ones (With no offense sir Qiang ;D )

I don't know if it's the optimal way to do this but I crafted a solution with Symfony YAML that produces a double interface consisting:
1. A php config array to Yii
2. A yml structure to user

This is possible just by adding a php tag on the top of configuration file
<?php
    Yii::import('system.vendors.SymfonyComponents.YAML.*');
    list(,$caller) = debug_backtrace(false);
    if($caller['file'] !== __FILE__)
      return sfYaml::load(__FILE__);
?>


All the necessary files to make it happen are included here Attached File  Symfony Yaml for Yii.zip (13.64K)
Number of downloads: 45

Installation process
1.(optional)Install Symfony YAML as described here
2.Go to the folder \PHP_installation_folder\PEAR (Yes I'm on Windows) and copy the folder SymfonyComponents or take it from the attachment
3.Paste it to Yii_path\framework\vendors
4.Create a new Yii web app and copy yml attachment files to your_new_web_app\protected\config folder

For new files to get involved, these should simply be renamed as php (remove the yml extension) or, mainly for code highlight reasons, change the $config assignment adding the ".yml" extension at the end of the reference path in the following files of your_new_web_app folder
1. index.php line 5
2. index-test.php line 9
3. protected\yiic.php line 5
4. protected\tests\bootstrap.php line 5

Please read the The YAML Format, an excellent single page documentation, for further details about the topic.

I'll be happy to know your opinion about this (or my English <_< )

Happy coding!!

[CORRECTION]
In file main.php.yml and line 45 please replace db file name testdrive1.db with testdrive.db (remove the '1')
Giving is not a service to community but to myself.
Because being exposed to people I deeply respect, resets my mind to life
1

#2 User is offline   phtamas 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 529
  • Joined: 26-February 11
  • Location:Mezőtúr, Hungary

Posted 01 April 2011 - 01:15 AM

Nice idea, simple and elegant implementation.
One possible problem:

Parsing a YAML file on every request may have significant impact on application's performance. It's worth caching the result array in a php file by using var_export() and parse the original YAML file again only when it changes.

0

#3 User is offline   stefanos 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 09-February 11

Posted 01 April 2011 - 07:09 PM

View Postphtamas, on 01 April 2011 - 01:15 AM, said:


Parsing a YAML file on every request may have significant impact on application's performance. It's worth caching the result array in a php file by using var_export() and parse the original YAML file again only when it changes.



Yes indeed, actually in my system this approach is 66 times slower.

So based on your suggestion:
<?php
    @include $tmp = __FILE__ . '.cch';
    if(@filemtime($tmp) < filemtime(__FILE__))
    {
      file_put_contents($tmp, '<?php $config = null;');
      Yii::import('system.vendors.SymfonyComponents.YAML.*');
      file_put_contents($tmp, '<?php $config='. var_export($config=sfYaml::load(__FILE__), true).';');
    }
    if($config !== null) 
      return $config;
?>


This makes importing only 2 times slower than plain php (practically is about 6 additional secs after 10000 requests).

I suppose this should be replaced only in main.php.yml and the cache file 'main.php.yml.cch' should not be deployed on a destination server.

Thank you phtamas :)
Any other suggestions are welcomed
Giving is not a service to community but to myself.
Because being exposed to people I deeply respect, resets my mind to life
0

#4 User is offline   elrond 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 10
  • Joined: 27-March 12

Posted 29 January 2013 - 05:00 AM

How about creating cli command to generate configs in production mode ?? (so it could be run as post-deploy action)

And what about icluded configs? (like we have one general config which is merged with local seettings)
0

#5 User is offline   pepe84 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 04-November 13

Posted 04 November 2013 - 01:08 PM

How about using APC to avoid reading YAML file every time?

index.php

<?php

// Set constants based on environment
define('YII_ENV', getenv('YII_ENV') ?: 'production');
define('YII_DEBUG', filter_var(getenv('YII_DEBUG'), FILTER_VALIDATE_BOOLEAN));

// Specify how many levels of call stack should be shown in each log message
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

// Required files
$yii = dirname(__FILE__) . '/../framework/yii.php';
$config = dirname(__FILE__) . '/protected/config/main.php';

// This is the main Web application configuration. Any writable
// CWebApplication properties can be configured here.
require_once($yii);
Yii::createWebApplication($config)->run();


main.php

<?php

// Uncomment the following to define a path alias
$path = realpath(dirname(__FILE__) . '/..');
Yii::setPathOfAlias('local', $path);

// Try to retrieve from cache first
if (!YII_DEBUG && function_exists('apc_fetch')) {
    $apcKey = 'app_config_' . YII_ENV;
    $config = apc_fetch($apcKey);
}

// If not cached, parse config file
if (YII_DEBUG || empty($config)) {
    // Use namespaced library
    Yii::setPathOfAlias('Symfony', $path . '/vendor/Symfony');
    $yaml = \Symfony\Component\Yaml\Yaml::parse($path . '/config/main.yml');
    $config = $yaml[YII_ENV];
    // And cache it
    if (!empty($apcKey)) {
        apc_store($apcKey, $config);
    }
}

// This is the main Web application configuration. Any writable
// CWebApplication properties can be configured here.

return $config;


Notice that now is possible to have configuration per environment (devel, production, etc) and inheritance too.

main.yml

production: &default
  ...
development:
  <<: *default
  ...


I hope this would be helpful for YAML fans.

Cheers.
Pepe

PS: I have Yaml component at vendor/Symfony/Component/Yaml folder.
0

#6 User is offline   ORey 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,699
  • Joined: 20-April 09
  • Location:Moscow, Russia

Posted 04 November 2013 - 01:26 PM

What's the profit?
For me
foo: bar
baz: qux

and
'foo' => 'bar'
'baz' => 'qux'

are pretty much the same.
God is real unless declared as integer
0

#7 User is offline   pepe84 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 04-November 13

Posted 05 November 2013 - 02:28 AM

It's just more clean. You don't have to write array() all the time. Nothing more.

Ah, and I forgot to mention the inline inheritance. It's very useful when you have lots of environments. In my case, I've all the configuration in one file.

main.yml
## YAML Template.
production: &default
  ...
    
development: &devel
  <<: *default
  ...
        
console:
  <<: *devel

test:
  <<: *devel
  ...


console.php
<?php

define('YII_ENV', 'console');
$config = require_once dirname(__FILE__) . '/main.php';
return $config;


test.php
<?php

define('YII_ENV', 'test');
$config = require_once dirname(__FILE__) . '/main.php';
return $config;

0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users