Trying to master OOP - Can anyone kindly advise (code provided)

Hello,

I’m in the process of learning OOP and have a few questions with the simple example i’m trying to use to query the table ‘test’ that I was hoping someone could help me with as I have a few questions before I can move on that i’d really like to understand.

  1. I’ve created a constructor, but for some reason my page outputs a mysql_connect() message, almost like the public attributes have not been passed to the construct method. I’ve double checked the details and they are all fine. Anyone see any issues?

  2. In my class Database I have my attributes defined as ‘private’. Is that right? What i’m basically thinking here is that my class Database will hold all database queries, so they would be no need to make them public or protected right?

  3. Does every class I create in my system need a construct method. Ie a general rule whenever you create a class nomatter what it is start with a constructor method?

  4. You don’t really need a destructor method in your classes unless you are doing something like closing a database connection ie with my below above?

  5. In my method query() I echo back a message with css styling. Is there any kind of general unwritten rule which says styling should be set outside the class in CSS?


<?php

class Database { 

 private $host;
 private $username;
 private $password;
 private $database;

 function __construct() {
   $conn = mysql_connect($this->host,$this->username,$this->password);
   mysql_select_db ($this->database,$conn) or die (mysql_error());
 }

 function query() {
   $SQL = "SELECT * from test";
   $QUE = mysql_query($SQL) or die (mysql_error());
     while($RES = mysql_fetch_array($QUE)) {
       echo "". $RES['id']."<br />";
       echo "". $RES['name']."";
	 }
 }
 
 function __destruct() {
   mysql_close($conn);
 }

}

//Create an instance of the class Database
$conn = new Database;

// and run the connect method to connect to database
$conn->host = "localhost";
$conn->username = "***********";
$conn->password = "*****";
$conn->database = "************";

//Now grab that data from the table
$conn->query();
?>

When you create the instance of your class, the __construct method will be executed.
In your example, when the constructor is executed, no values are stored in your private variables.

Using private variables, means that you only have access to them within the class it self.
In your example, you try to set values from outside of the class, thats not possible.
Either make the variables public, or alter your constructor to accept the four values


class database{
   private $conn;
   public function __construct($host, $username, $password, $database) {
      $this->conn = mysql_connect($host,$username,$password);
      mysql_select_db ($database,$this->conn) or die (mysql_error());
   }
}
$conn = new database('localhost','*****','*****','******');


It would be best not to echo anything from within the class itself… Let the class return values instead, that way it will be much more flexible.
Also, wouldnt it be nice to be able to select from other tables?
Take a look at the select_all_from() method…


class database{
   private $conn;
   public function __construct($host, $username, $password, $database) {
      $this->conn = mysql_connect($host,$username,$password);
      mysql_select_db ($database,$this->conn) or die (mysql_error($this->conn));
   }

   public function select_all_from($table) {
      $SQL = "SELECT * from ".$table;
      $QUE = mysql_query($SQL,$this->conn) or die (mysql_error($this->conn));
      $data = array();
      while($RES = mysql_fetch_array($QUE)) {
          $data[] = $RES;
       }
      return $data;
   }
}

$conn = new database('localhost','*****','*****','******');
$result = $conn->select_all_from('tablename');
foreach($result as $row => $data){
   echo $data['id'].'<br />';
   echo $data['name'];
}

Bear in mind, that if you select from a table with alot of records or with alot of data, that method will use alot of memory… but if its only for small datasets it will do fine.

Don’t forget to do this as well…

I think something like this should work:

public $conn;

Yep, the __construct method is one of those magic methods. It’s only automatically called when something else is done. In this case, creating a new class.

Thanks Guys,

I understand now OopNoob’s posting makes it make sense when he says:

You can not pass variable values to the __construct method after the class has been instantiated

Thanks

Hello,

I’m new to OOP as well, but I’m going to provide my 2 cents…please see my code comments below…


<?php

class Database { 

 public $host;
 public $username;
 public $password;
 public $database;

 function __construct() {
   $conn = mysql_connect($this->host,$this->username,$this->password);
   mysql_select_db ($this->database,$conn) or die (mysql_error());
 }
 
 function __destruct() {
   mysql_close($conn);
 }

}

/*
The moment you instantiate (create) a new class it automatically 
causes the __contruct method to run.  Since the following line 
of code does not provide the values of the class variables, the 
__construct method runs without any class variable values.  
Thus, the connection fails.  You can not pass variable values to 
the __construct method after the class has been instantiated.  
If you want to make it work, you must instantiate (create) the 
new class using a statement that provides the class variable 
values.  Just like someone pointed out above, you should use:
$conn = new database('localhost','*****','*****','******');
*/
//Create an instance of the class Database
$conn = new Database;

/*
If you use:
$conn = new database('localhost','*****','*****','******');
You can delete the 4 lines of code below.
*/
// and run the connect method to connect to database
$conn->host = "localhost";
$conn->username = "*********";
$conn->password = "********";
$conn->database = "****";

?>

That’s because you’re creating a new database class, which (in the constructor) attempts to connect to the database. But it can’t, as it doesn’t have the connection details yet.

So in this case you need to provide the database connection details when you instantiate the object ($conn = new Database) like Zalucius suggested.

Also, when your desctructor is called (once it’s all working), it will try to access a variable called $conn, but that variable doesn’t exist. You need to store $conn as a member of the object too (e.g. $this->conn).

Try this:

Thanks guys, that’s really helpful. Still confused on one thing though.

I’ve made my attributes in my code public rather than private, so they can be set outside the class like so:


<?php

class Database { 

 public $host;
 public $username;
 public $password;
 public $database;

 function __construct() {
   $conn = mysql_connect($this->host,$this->username,$this->password);
   mysql_select_db ($this->database,$conn) or die (mysql_error());
 }
 
 function __destruct() {
   mysql_close($conn);
 }

}

//Create an instance of the class Database
$conn = new Database;

// and run the connect method to connect to database
$conn->host = "localhost";
$conn->username = "*********";
$conn->password = "********";
$conn->database = "****";

?>

But am still getting a mysql_connect() message and I can’t get my head around why. I realise I could pass the values in the parameter of the instance Database I created, or even define them in the class like so and that does work:


 public $host = "localhost";
//etc...

But I just don’t get why the above code does not work and i’d like to get that clear in my head.

Thanks

  1. Since you’ve defined the variables as private, you cannot read or write them outside of the class itself. As zalucius pointed out, you need to pass the the data as parameters to the __construct method.

  2. Using private in this instance is fine.

  3. No, the constructor method is optional. If you don’t want to do anything upon creating the object, either leave the constructor empty, or don’t include one.

  4. Same with the constructor, it’s only needed if you want do something there.

  5. Like zalucius said, you should keep the database logic and display logic separate. The database class should only be concerned with retrieving the data it has been asked for, not on how it will be displayed.