-1

I have a class which loads my config.ini file and sets them as as objects/ object variables, I want these to be readable outside of the class yet protected from being changed? How can I accomplish this?

config.php

<?php

namespace app;

class config {

    public      $debug;
    private     $_data;

    public function __construct(){

        // parse config.ini
        $data = (object) json_decode(json_encode(parse_ini_file(BASE_PATH . DS . 'inc' . DS . 'app' . DS . 'config.ini', true)));

        // set debug
        $this->debug = (bool) $data->debug;

        // set data based on enviornment
        foreach($data->{$data->environment} as $key => $value){
            $this->_data->$key = (object) $value;
        }

        // turn on errors
        if($this->debug == 1){              
            error_reporting(E_ALL ^ E_NOTICE);
            ini_set("display_errors", 1);
        }

        // unset
        unset($data);

    }

    public function __get($name) {
        if (isset($this->_data->$name)) {
            return clone $this->_data->$name;
        } else {
            //
        }
    }

    public function __set($name, $value) {
        //
        echo 'ERROR';

    }


}
?>

app.php

<?php
// load config
$config = new app\config(); 

echo '<pre>';
print_r($config);
echo '</pre>';

$config->database->server = 'test';

echo '<pre>';
print_r($config->database);
echo '</pre>';

$config->_data->database->server = 'test';

echo '<pre>';
print_r($config->database);
echo '</pre>';

?>

output

    app\config Object
(
    [debug] => 1
    [_data:app\config:private] => stdClass Object
        (
            [database] => stdClass Object
                (
                    [server] => localhost
                    [database] => 
                    [username] => 
                    [password] => 
                )

        )

)

stdClass Object
(
    [server] => localhost
    [database] => 
    [username] => 
    [password] => 
)

stdClass Object
(
    [server] => localhost
    [database] => 
    [username] => 
    [password] => 
)

UPDATE: I have updated my code based on the comment given but I encountered two problems ...

1: In __get if I return return $this->_data->$name; I am able to modify it outside of the Class ... I resolved this with adding clone - return clone $this->_data->$name;

2: I can now not set or update the value with either $config->database->server = 'test'; or $config->_data->database->server = 'test'; BUT ... no error / exception is reported, and I even tried to just echo something with __set and nothing ...

cmorrissey
  • 8,493
  • 2
  • 23
  • 27
  • 2
    I think the link offered by @lonesomeday is overly complicated. Just make the attribute protected, and then offer a public getter function for read-only access. There's no need to throw an error if external code tries to write its value - PHP will do that for you. – halfer Nov 01 '13 at 20:49
  • I have updated my question after reviewing comments but I have some additional problems now. – cmorrissey Nov 01 '13 at 22:33
  • Have you considered using constants? – Jonast92 Nov 01 '13 at 22:35
  • @Jonast92 can you give me an example of how that would work with what im doing? – cmorrissey Nov 01 '13 at 22:36

1 Answers1

2

Members need to be private. Use only a get function to get their values, but they cannot be modified from outside the class. Example:

class myClass{

     private $test;

     public function getTest()
     {   return $this->test;  }

}

How its called:

$classTest = new myClass();

$classTest->test  NOT ALLOWED
$classTest->getTest()    -- Returns the  value
Aris
  • 4,643
  • 1
  • 41
  • 38