# Require config file in class

I want to use the variables that have been declared in a config.php file in a class for testing. I am not sure if this is the right way like I have done it.

I have a configuration file, config.php:

class Config {

public $hosts = array( 'a' => '192.168.1.10' 'b' => '192.168.1.11', ); public$ports = array(
'a' => 22,
'b' => 22,
);
}


These are the variables I want to include in a file called Tests.php:

require_once 'config.php';

class Test extends PHPUnit_Framework_TestCase
{
protected $hosts; protected$ports;
...

public function __setUp()
{
$config = new Config();$this->hosts = $config->hosts;$this->portsSsh = $config->ports; ... } public function testConnect() {$session = $this->connect($this->hosts['a'], $this->ports['a']);$this->closeConnection($session); } ... }  Is it right doing it like this? I have the impression it is too complicated. I have to make a class for the config.php file and in the test class I have to do like a mapping $this->hosts = $config->hosts. That I don't like so much, because I have about 14 variables and first I have to declare them all and later I have to assign them all in the setUp() method. Isn't there a shorter or simpler way? I was thinking of using a loop and I don't want to use globals. I wonder if I should do it like this: require_once 'config.php'; class Test extends PHPUnit_Framework_TestCase { protected$hosts;
protected $ports; ... public function __setUp() {$this->config = new Config();
}

public function testConnect()
{
$session =$this->connect($this->config->hosts['a'],$this->config->ports['a']);
$this->closeConnection($session);
}
...
}

• If you need something to operate, ask it as a parameter in your __construct. If you need it to do a certain functionality (e.f. find) ask for it in that method. – Pinoniq Jan 20 '15 at 8:27

This 'problem' of yours can be solved using Separation of concern. Your Database class should not know about config and how it is loaded. It should simply ask for the stuff it needs. Neither should your Test class know how to connect. Your test class should test the Database class. And your database class should handle the 'connection failed' error of whatever library you are using.

For instance:

class DatabaseConnection
{
public function __construct($host,$username, $password,$port='22'){
if connection failed throw new ConnetionFailedException
}
}


Your would then also have a config class that loads the correct config file. e.g.:

class Config
{
public function __construct($enviroment) {$this->data = include __path_to_config_files_.'/'.$enviroment.'.inc'; } }  Your could for instance use a __get method to retrieve the data instead of having a getParameter. your config file would look something like this: __path_to_config_files_/development.inc <?php return array( 'key' => 'value' );  And your test class would then: $config = new Config('development'); //or whatever enviroment you are in
try {
$connection = new DatabaseConnection($config->db['host'], $config->db['username'],$config->db['password']);
} catch(ConnetionFailedException) {
//connection failed
}
//connection success


Maybe the use of parse_ini_file is appropriate here. Like suggested before I would definately create a Config object to allow flexibility and the ability to unit test without touching the file system. Something like this:

class Config
{

protected $config = array(); public function __construct($configFile)
{
$this->config = parse_ini_file('your/config/dir/' .$configFile . '.ini');
}

public function __get($key) { if (array_key_exists($key, $this->config)) { return$this->config[$key]; } throw new \Exception('Invalid configuration option: ' .$key);
}
}


This gives you a very flexible config object, only disadvantage is the use of automagic so hinting in your IDE doesn't work.