Reputation: 243
I need to access a configuration variable from inside a method in a public class. The file where the variable is stored is included into the ajax.php page where I also call the class constructor and his method
<?php
include_once('../config/config.php');
[...]
$myclass = new myclass();
$res = $myclass->mymethod();
echo json_encode($res);
?>
I tried to print the $config variable stored into config.php from inside the myclass method mymethod and it doesn't do anything. If I try to call include_once('../config/config.php') it doesn't load anything and the $config varialbe is always empty, while if I try to include('../config/config.php') I can access the $config variable data without problem.
So, if I understand correctly how include and include_once works, the _once just skip to import the file 'cause it has already been included before. My question is, how can I access $config without being forced to include it again with include (not _once) ?
Upvotes: 0
Views: 799
Reputation: 141
As a another way to do the same thing as was suggested before:
config.php
<?php
return array(
'hostname' => 'localhost',
'username' => 'dev',
'passwrod' => '',
);
MyConfig.php
<?php
class MyConfig extends ArrayObject
{
public function __construct($filename)
{
parent::__construct();
$this->setFlags(ArrayObject::ARRAY_AS_PROPS);
if (!is_readable($filename)) {
throw new InvalidArgumentException("Invalid file name: ".$filename);
}
$loaded_data = include($filename);
foreach ($loaded_data as $index => $value) {
$this->offsetSet($index,$value);
}
}
}
And then you can use like this MyClass.php
class MyClass{
private $config;
public function __construct($config){
$this->config = $config;
}
public function mymethod(){
return $this->config->hostname .":". $this->config->username;
// or even
//return $this->config['hostname'] .":". $this->config['username'];
}
}
the nice thing about MyConfig inheriting ArrayObject is that you can use the array values as properties.
Upvotes: 1
Reputation: 20469
Your problem is understanding variable scope. You need a way to make your config array accessible to your class level methods.
The simplest method would be to pass a copy to the class in the constructor (or the individual method if it is only required in one):
//config.php
$config=array(
'something'=>'value',
'somethingelse'=>10
);
//myclass.php
class MyClass{
private $config;
public function __construct(array $config){
$this->config = $config;
}
public function mymethod(){
return $this->config['something'];
}
}
//index.php
include_once('../config/config.php');
$myclass = new MyClass($config);
echo $myclass->mymethod();//outputs 'value'
If this is purely readonly another option would be to wrap config array in a static class method:
//config.php
class Config{
public static function getConfig(){
return array(
'something'=>'value',
'somethingelse'=>10
);
}
}
//index.php
include_once('../config/config.php');
//anywhere in your code
$config = Config::getConfig();
echo $config['something'];
This initializes a new array every time its called so its not a great option.
A third option would be to wrap your config in a singleton class, which is initialized only once but available via a static method call anywhere
//config.php
class Config{
public $config;
private static $inst=null;
private function __construct(){
$this->config=array(
'something'=>'value',
'somethingelse'=>10
);
}
public static function Instance(){
if(static::$inst==null){
static::$inst=new Config();
}
return static::$inst;
}
}
//index.php
include_once('../config/config.php');
//anywhere in your code
echo Config::Instance()->config['something'];
The singleton pattern is convenient, but has its (often debated well publicised) problems.
Ultimatly the 1st option is probably what you need.
Upvotes: 2