Jump to content

PHP5 __get() I don't understand.


JustinK101

Recommended Posts

I am trying to use the magic function __get to return values of private class member variables but its not working. Thanks for the help.

 

       class DatabaseConfiguration {
	private $host = "localhost:3306";
	private $database = "database";
	private $username = "username";
	private $password = 'password';

	public function __get($var) {
		return ($this->$var);
	}	
}

 

The I want to do:

 

$instance->host and get the value of host. I have gotten used to the C# style of doing this, but this is the point of __get() right? So you don't have to write methods for each class member variable like public function get_host() { return $this->host; }

Link to comment
https://forums.phpfreaks.com/topic/101657-php5-__get-i-dont-understand/
Share on other sites

I think you've missed the point here...

 

__get is a function which is called when reading the value of undefined property. For example:

 

class test
{
  public $a = 10;
  //public $b = 10;
  
  public function __get($var) {
     print "Retrieve failed...\n";
  } 
}

$test = new test();
echo $test->b; // will output: Retrieve failed.

 

You mainly use get to handle situations where you want to validate a member variable.

 

So in short, what you are doing will work, but isn't what __get was designed for.  Your code works on my machine fine:

 

$db  = new DatabaseConfiguration();
print $db->host;

Ok got it working. Below is the full code. So why inst the purpose of __get to do what I am doing? I though the point of a getter and setter was to give public access to private class variables. Why in world would you use __get and __set for class member variables that aren't even defined in the class.

 

abstract class DatabaseConfiguration {
	private $host = "localhost:3306";
	private $database = "database";
	private $username = "username";
	private $password = 'passwod';

	public function __get($var) {
		return ($this->$var);
	}	
}

 

class DatabaseConnection extends DatabaseConfiguration {
	private static $instance;
	private $db_connection;

	private function __construct() {}

	public function __destruct() {
		mysql_close($this->db_connection);
	}

	public static function singleton() {
		if(self::$instance == null) {
			self::$instance = new self;
		}
		return self::$instance;
	}

	public function connect() {
		$this->db_connection = @mysql_connect(parent::$this->host, parent::$this->username, parent::$this->password);

		if(empty($this->db_connection)) {
			trigger_error(mysql_error(), E_USER_ERROR);
		}

		if(!@mysql_select_db(parent::$this->database, $this->db_connection)) {
			trigger_error(mysql_error(), E_USER_ERROR);
		}
	}
}

DatabaseConnection::singleton()->connect();

AP81:

 

Should I make the class DatabaseConnection a singleton or just abstract. I don't think I am ever going to need an instance of it, so I am thinking just abstract, but I have read some articles that say your database connection should be a singleton. I don't get it though, once I open the MySQL connection I don't care about it anymore, why would I need a SINGLE singleton instance of the class hanging around?

Using a Singleton for a database connection is debatable.  Some people are for, some against. 

 

It is very useful because you are not constantly opening and closing connections, and you are never opening more than one connection to the database. You are instead only opening a connection at the last possible moment, and reusing the connection later (if necessary).

 

Saying that, there is a couple of things you could improve on.  Your Database connection class still allows for multiple instances because it can be cloned.  For example if you did this, it would allow another instance of your class:

 

  $a = DatabaseConnection::singleton()->connect();
  $b = clone $a; // b is now a new instance

 

Add this to your class:

  public function __clone() {
    throw new exception("Class cannot be cloned!"); // or whatever message you want
  }

 

Now you class can't be cloned. 

 

As for making the DatabaseConnection class abstract, I don't think there is much benefit to it.  In situations like this, I use interfaces, i.e.

 

<?php

Interface DB 
{
  private function Connect();
  public function Query ($query);
  public function GetRowCount();
  public function GetRowsAffected();
}

// fill these methods in 
Class DatabaseConnection implements DB
{
  private function Connect() {
   //
  }

  public function Query ($query) {
   //
  }
  
  public function GetRowCount(){
    //
  }
  
  public function GetRowsAffected() {
   //
  }

}

?>

 

"A single connection object can then be used throughout your code, as opposed to creating many additional connection objects which will eat up your resources. That would be the reason I guess."

 

So what you store the singleton DatabaseConnection class object in a session so you can use it on other pages? I don't quite understand how the singleton allows you to only open a database connection once and reuse it.

"A single connection object can then be used throughout your code, as opposed to creating many additional connection objects which will eat up your resources. That would be the reason I guess."

 

That means if, say you had two classes that both required a database connection you could do something like:

 

<?php 

class foo {
    protected $_db;

    public function __construct(){
        $this->_db = DatabaseConnection::getInstance();
    }
}


class bar {
    protected $_db;

    public function __construct(){
        $this->_db = DatabaseConnection::getInstance();
    }
}
?>

 

Then instead of creating two connection to the database, it would be like:

<?php

$db = DatabaseConnection::getInstace()->connect($dbSettings);

new foo();
new bar();

?>

 

Now both classes foo and bar have access to the database, but you only connected once.

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.