Jump to content

Recommended Posts

Hey!

 

I have a config class in my small framework, where all the properties are private.

I had a get method which I would call to, obviously, get the data from the private properties.

But one day I had the idea to use __get to retrieve the values by just calling $config->propertie instead of $config->get("propertie")

 

I only do it this way to make sure all the data in the config class is unchangeable at runtime and I can easily  access it.

 

I know this is not the greatest use of the __get magic method, but is it that horrible? It's just for this special config class :D

 

What do you guys think?

Link to comment
https://forums.phpfreaks.com/topic/120227-getting-private-values-from-the-outside/
Share on other sites

In the OOP ideology world, __get and __set are evil.  Straight up evil.  Well, kind of.

 

__get entirely breaks the idea of encapsulation.  Why declare variables as private if you can just get them through __get()?  Anyway, I'm sure someone better versed in OOP than I will come along.

 

 

Oh, I should note that I'm guilty of using __get() too.

Yes, as I said I had the get method, but I just started to use __get because it was simpler to just call the properties instead of calling the method to call the properties. I know that basically that is still what I do, since __get is a method and that method is called when I do $config->propertie, but this way it just looks nicer, I guess.. no real reason to do it this way.. it's just because I can and it looks nice :D

No, I think I have blue stars because I've been around longer and more active. Doesn't make me smarter by any measure.

 

Also, I proposed you for those pretty yellow thingies. So I guess that means I do think you are pretty smart, don't you agree?

Hehe. I was just making a joke, but all kidding aside you are much better than I when it comes to the nitty gritty details on various design patterns and a lot of best practices. While I try to take these things into account I typically take the route that seems the most logical to me. In general, I just try to write code that is pretty readable so that it's easier to maintain downstream.

 

Thanks for the nomination! I hope that you're still happy with your decision.

Like someone else already said, __get/__set breaks encapsulation which begs the question why not make it public and remove the overhead.

 

Accessor functions i think is that way to go.  This allows you to make sure data that is passed it correct and perform extra functionality if needed.

I more or less just do config classes like this. The main thing is having any data that is going to be used multiple places easily available. While this solution certainly isn't anything elaborate, that's what makes it powerful in my eyes. If you keep your feature set simple, easy to use, and easy to read (maintain) it will allow you to add on and grow as necessary. If you're looking for a more elaborate implementation make sure your needs warrant it. Complex systems are often harder to maintain longterm.

 

class Config
{
   public __construct() { }

   public getValue($key)
   {
      $arr = array();
      $arr['username'] = "user";
      $arr['token'] = "1352sdcvdstr4";

      if( isset($arr[$key]) ) { return $arr[$key]; }
      return "";
   }
}

$config =  new Config();
echo $config->getValue('token');

 

 

The config class I use has an accessor method.  It's like this:

 

<?php

class Config {

private $settings = array();

public function __construct() {
	$this->settings = parse_ini_file('includes/Config.ini', true);
}

public function Get($name) {
	if(strpos($name, '::') === false) {
		if(array_key_exists($name, $this->settings)) {
			return $this->settings[$name];
		}
	}
	else {
		$parts = explode('::', $name);
		if(array_key_exists($parts[0], $this->settings)) {
			if(array_key_exists($parts[1], $this->settings[$parts[0]])) {
				return $this->settings[$parts[0]][$parts[1]];
			}
		}
	}

	$trace = debug_backtrace();
	trigger_error(
		'Undefined property: ' . $name .
		' in ' . $trace[0]['file'] .
		' on line ' . $trace[0]['line'],
		E_USER_NOTICE);
	return null;
}

public static function GetInst() {
	static $inst = null;
	if($inst == null) {
		$inst = new Config;
	}
	return $inst;
}

}

$db = new CDB(Config::GetInst()-Get('db'));
//or to get just the DB host:
echo Config::GetInst()-Get('db::host');

 

 

(Yes, I realize I could abstract out the parsing and easily make it not bound to ini files.)

 

(Disclaimer:  I think I may have stolen this from somewhere a long time ago and modified it, so if it looks familiar, that's why.)

 

 

 

 

 

 

 

 

Oh, I have a question.  Earlier you said you don't want the vars public because then they could be changed.  Why would anyone ever want to change them?

Like someone else already said, __get/__set breaks encapsulation which begs the question why not make it public and remove the overhead.

 

Accessor functions i think is that way to go.  This allows you to make sure data that is passed it correct and perform extra functionality if needed.

 

And why, may I ask, do these magic methods break encapsulation more than accessor methods?

 

Yes, you can misuse __get and __set, and break encapsulation. But this is NOT a property inherent to these magic methods, it's programmer fault.

 

If __get and __set delegate to my accessor (mutator) methods, it doesn't break encapsulation any more than my accessor methods. If I only have a __get method, and no accessor method (not recommended), it doesn't break encapsulation, as long as I code defensively.

 

Really. Can people please stop simply echoing others?

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.